Страницы

Поиск по вопросам

среда, 10 июля 2019 г.

Выбор наиболее специфичного типа аргумента при вызове перегруженного метода в Java

Известно, что если при удовлетворении сразу нескольких перегруженных методов вызову, выберется тот, аргумент которого наиболее специфичен. Пример:
class Test { void t(Object o) {System.out.println("Object");} void t(Integer i) {System.out.println("Integer");} public static void main(String[] s) { new Test().t(null); } }
В данном случае выдастся то, что и должно - Integer (Integer имеет 1 уровень наследования от Object). Если же добавить ещё 3 метод с аргументом String, произойдёт ошибка, т. к. у Integer и у String уровень наследования равняется 1. Теперь рассмотрим другой пример:
class B1 {} class E1 extends B1 {} class EE1 extends E1 {} class B2 {} class Test { void t(B2 e) {System.out.println("B2");} void t(EE1 e) {System.out.println("EE1");} public static void main(String[] s) { new Test().t(null); } }
Если попробовать его запустить, произойдёт ошибка, не удалось выбрать наиболее специфичный тип! Хотя в случае EE1 имеется 3 уровня наследования, а у B2 1 уровень наследования. И финальный пример:
class B1 {} class E1 extends B1 {} class EE1 extends E1 {} class Test { void t(E1 e) {System.out.println("E1");} void t(EE1 e) {System.out.println("EE1");} public static void main(String[] s) { new Test().t(null); } }
Отрабатывает корректно. Выдаётся EE1. С чем связано такое поведение? Почему при ветвлении наследования не происходит определения специфичности на основании удалённости от Object?


Ответ

Можно сделать выбор только между базовым классом и наследником (можно через другой класс) в пользу наследника. Между 2 любыми наследниками из разных "веток" выбор сделать нельзя.
Вас же не удивил пример 1 после добавления String, Integer наследуется от Number и является наследником 2 порядка и по вашей логике должен выбираться именно он. Хотя такое поведение было бы, мягко говоря, странным.

Комментариев нет:

Отправить комментарий