java构造函数行为继承和静态/动态绑定

Yar*_*lam 4 java inheritance constructor

所以我有以下3个类:

带有1个字段和1个构造函数的类"A",用于调用方法:

public class A {
    String bar = "A.bar";

    A() {
        foo();
    }

    public void foo() {
        System.out.println("A.foo(): bar = " + bar);
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个类"B",它继承自A,包含1个字段和1个调用方法的构造函数:

public class B extends A {
    String bar = "B.bar";

    B() {
        foo();
    }

    public void foo() {
        System.out.println("B.foo(): bar = " + bar);
    }
}
Run Code Online (Sandbox Code Playgroud)

包含主要方法的第三类"C":

public class C {
    public static void main(String[] args) {
        A a = new B();
        System.out.println("a.bar = " + a.bar);
        a.foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

B.foo():bar = null

B.foo():bar = B.bar

a.bar = A.bar

我在调试模式下跟踪程序,我仍然无法弄清楚输出.我将非常感谢对所发生的过程及其背后的原则的详细解释.非常感谢.

编辑:就像人们指出我确实忘记了输出的最后一行是:

B.foo():bar = B.bar

Mil*_*kic 5

首先调用B类的构造函数.但是,如果扩展一个类而不显式调用基类的构造函数(或派生类的其他构造函数),那么每个默认构造函数的第一行都是(隐藏)调用super(),即基类的构造函数(在这种情况A).所以,我们正在进行A的构造函数,它调用方法foo().由于此方法在B类中被覆盖,因此会调用overriden实现.事情现在变得很有趣 - B的构造函数仍然没有完成,所以bar仍然没有设置值,因此输出:

B.foo(): bar = null
Run Code Online (Sandbox Code Playgroud)

我们现在回到B的构造函数中,它的输出

B.foo(): bar = B.bar
Run Code Online (Sandbox Code Playgroud)

最后,输出

a.bar = A.bar
Run Code Online (Sandbox Code Playgroud)

是由于变量阴影.