Допустим, что у нас есть следующий код:
class A {
public void doLogic() {
System.out.println("doLogic from A");
}
}
class B extends A {
@Override
public void doLogic() {
System.out.println("doLogic from B");
}
public void doDifferentLogic() {
System.out.println("doDifferentLogic from B");
super.doLogic();
}
}
class C extends B {
@Override
public void doLogic() {
System.out.println("doLogic from C");
}
}
public class Test {
public static void main(String[] args) {
C c = new C();
c.doDifferentLogic();
}
}
Когда мы выполняем этот код, ожидаемое поведение выглядит следующим образом:
Так как c содержит ссылку на объект класса C, когда вы вызываете метод c.doDifferentLogic()
, JVM ищет метод в классе C и, поскольку он не найден, он начинает искать дерево наследования. Как и ожидалось, метод doDifferentLogic()
находится в суперклассе и выполняется. Однако ожидается, что конструкция super.doLogic()
будет выглядеть из текущей ссылки "Точка зрения", которая имеет тип C. Таким образом, супер C должен быть B, но вместо этого вызывается метод из верхнего класса A.
Если вы удалите ключевое слово super
или замените его на ключевое слово this
(то же самое, что и "this" неявно), вы получите ожидаемое полиморфное поведение и вызывается doLogic()
из класса C.
Итак, мой вопрос:
Должен вызывать super.doLogic()
be this.super.doLogic()
(2) вместо static.super.doLogic()
(1)?
Оба являются недопустимыми конструкциями, они здесь просто для того, чтобы лучше объяснить себя.
(1) или другими словами - из ссылки на текущий объект c, получить суперкласс текущего объекта и вызывать метод doLogic()
вместо
(2) из этого класса получить суперкласс и вызвать его метод doLogic()
?