Известно, что если при удовлетворении сразу нескольких перегруженных методов вызову, выберется тот, аргумент которого наиболее специфичен. Пример:
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 порядка и по вашей логике должен выбираться именно он. Хотя такое поведение было бы, мягко говоря, странным.
Комментариев нет:
Отправить комментарий