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

标签 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);
    }
}

第二个类“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);
    }
}

包含主要方法的第三个类“C”:

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

输出是:

B.foo(): bar = null

B.foo(): bar = B.bar

a.bar = A.bar

我在 Debug模式下跟踪程序,但我仍然不太清楚输出结果。如果能详细解释发生的过程及其背后的原则,我将不胜感激。 非常感谢。

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

B.foo(): bar = B.bar

最佳答案

首先调用 B 类的构造函数。但是,如果您扩展一个类并且没有显式调用基类的构造函数(或派生类的其他构造函数),那么每个默认构造函数的第一行都是(隐藏)调用 super(),即基类的构造函数(在本例中为 A)。因此,我们正在处理 A 的构造函数,它调用方法 foo()。由于此方法在类 B 中被重写,因此调用重写的实现。现在事情变得有趣了 - B 的构造函数仍然没有完成,所以 bar 的值仍然没有设置,因此输出:

B.foo(): bar = null

我们现在回到 B 的构造器,它输出

B.foo(): bar = B.bar

最后输出

a.bar = A.bar

是由于variable shadowing .

关于java构造函数行为继承和静态/动态绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31075040/

相关文章:

java - 在 Faro 洗牌期间跟踪选择的扑克牌

java - 将 SoapUI 插件与 Jenkins 集成

java - 为什么这段代码不能编译?

java - 包中的基类和派生类

java - 我使用的方法、构造函数和 getter 正确吗?

java - 如何在 Perl 中动态构建 Java 类路径?

java - 在没有事件的情况下检索 JavaFX 中的鼠标位置

vb.net - 重写 VB.NET 中的 Sub 过程

c++ - 如何在调用派生类构造函数之前设置基类成员?

c++ - 初始化器列表 *argument* 评估顺序