Java中的超级关键字,有趣的行为,请解释一下

Ант*_*нов 25 java inheritance super

可以说我们有以下代码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我们执行这段代码预期的行为是:由于C拥有一个参考对象C类的,当你调用c.doDifferentLogic()的JVM搜索在C类中的方法方法,因为它没有发现它开始盯着继承树.正如预期的那样,该doDifferentLogic()方法可以在超类中找到并执行.然而,构造super.doLogic()期望从当前引用的"Point of View"看起来是C类型的.因此C的超级应该是B,而是调用来自顶级A的方法.

如果删除super关键字,或者将其替换为this关键字(与"this"隐含相同),则会获得预期的多态行为,并doLogic()调用from C类.

所以我的问题是:应该打个电话super.doLogic()this.super.doLogic()(2),而不是static.super.doLogic()(1)?

两者都是无效的结构,它们只是为了试图更好地解释自己.

(1)或者换言之-从参考到当前对象C,获得当前对象的父类,并调用doLogic()从这个类方法代替(2)得到的超类并调用它的doLogic()方法?

tem*_*def 50

在Java中,super关键字始终引用使用关键字的类型的超类,而不是调用方法的对象的动态类型的超类.换句话说,super是静态解决,而不是动态解决.这意味着在类的上下文中B,super关键字始终引用类A,无论该B方法是否使用C对象作为接收器执行.据我所知,没有办法动态确定超类类型并使用其方法而不使用反射.

希望这可以帮助!

  • 只是为了补充这个优秀的答案,当引用基类上定义的方法时,调用`super.doLogic()`将走向继承层次结构,直到它找到要执行的`doLogic()`方法的具体实现. . (3认同)