Я написал код вроде
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");
}
@Override
public String show(A obj) {
return ("B and A");
}
}
class Solution {
public static void main(String[] args) {
A ab = new B();
B b = new B();
System.out.println(ab.show(b));
}
}
Результат - B и A. Я не понимаю, почему это не B и B, поскольку b - объект B. Но если я изменю От A ab = новый B () до B ab = новый B () Результатом будут B и B. Почему это так?




Поскольку ab - это A, он вызывает виртуальный A.show, но поскольку ab на самом деле является B, фактический вызываемый метод является заменой B виртуального метода исходного A.
Компилятор Java использует статическую привязку к типам аргументов, передаваемых в качестве параметров. Это определяет, какой перегрузка вызывается в классе типа переменной, здесь A.
Статический тип ab - это A, поэтому единственный подходящий метод с именем show - это show(A).
JVM использует динамическую привязку по отношению к типам времени выполнения объектов, для которых вызываются методы. Это определяет, какой отвергать вызывается. Это полиморфизм.
Тип среды выполнения ab - B. В show(A) есть переопределение B, поэтому это вызываемый метод, который печатает «B и A».