У меня есть этот вопрос, связанный с наследованием, полиморфизмом, перегрузкой и переопределением. Я понимаю все эти термины, но не уверен, как они работают здесь. Вот код:
class A {
public String show(D obj) {return "A and D";}
public String show(A obj) {return "A and A";}
}
class B extends A {
public String show(B obj) {return "B and B";}
public String show(A obj) {return "B and A";}
}
class C extends B{}
class D extends B{}
public class whatever {
public static void main(String[] args) {
A a = new B(); // note the B here
B b = new B();
C c = new C();
D d = new D();
System.out.println(a.show(a)); // B and A
System.out.println(a.show(b)); // B and A
System.out.println(a.show(c)); // B and A
System.out.println(a.show(d)); // A and D
}
}
Итак, задача здесь состоит в том, чтобы найти выход. У меня уже есть ответы, это комментарии, которые я оставил.
Я понимаю первое, потому что Java автоматически выполняет динамическую привязку, поэтому a.show() вызывает show() из класса B, а a имеет тип A, поэтому вызывается B.show(A obj).
Последнее тоже имеет смысл, метод show() перегружен, и поскольку d имеет тип D, вызывается A.show(D obj), унаследованный от класса A.
С двумя другими у меня проблемы. Ну, я понимаю, что это имеет смысл, потому что b и c технически являются объектами типа A, но почему это идет с «B и A», а не с «B и B»?




Объявленный тип a — A.
A имеет только два метода: один принимает A (и оба b, и c являются экземплярами A), а другой принимает D (и ни b, ни c не являются экземплярами D).
Итак, первый метод подходит, а второй нет. Таким образом, первый метод выбирается компилятором.
Этот метод переопределен в B, а конкретный тип a — B, поэтому печатается «B и A».
Метод B.show(B) не переопределяет метод A.show(A), так как он не принимает тот же тип в качестве аргумента.
Здесь есть две концепции: одна для перегрузки, а другая для переопределения. Когда вы создаете A a = new B(); это означает, что a является объектом B и имеет тип A . Поэтому, когда выполняется a.show(a), он сначала сталкивается с методами show(A obj) и show(B obj) класса A, а затем сопоставляет параметр с типом A, но 'a' является экземпляром B, поэтому метод show(A obj) класса B.
Теперь, когда выполняется a.show(c), он сначала встречает методы show(A obj) и show(B obj) класса A, а затем не находит совпадений с параметром типа C внутри класса A, но все равно выполняется потому что класс C расширяет B, а B расширяет A.
Подводя итог вкратце, можно сказать, что a.show(a) эквивалентен a.show(b) и эквивалентен a.show(c).
О, так он сначала смотрит на объявленный тип, а затем выбирает переопределенный метод. Я думал об этом в обратном направлении, я думал, что он просто сразу смотрит на конкретный тип. Спасибо за помощь!