为什么子 class 构造函数在初始化父部分时使用了方法的重写版本?

Why child class constructor when initializing parent's part used overrided version of method?

为什么 B() 在使用 class B 中定义的重写方法 print() 初始化 class A 的一部分时?

预期输出:
A
4

实际输出:
0
4

public class Test
{
    public static void main(String[] args)
    {
        new B();
    }
}

class A
{
    public A()
    {
        print();
    }
    
    public void print()
    {
        System.out.println("A");
    }
}

class B extends A
{
    int a = 4;
    public B()
    {
        print();
    }
    
    @Override
    public void print()
    {
        System.out.println(a);
    }
}

您在 class B 中覆盖了 print

因此,如果您在 B 的实例上调用 print,它将始终到达那里。

当构造函数仍然是 运行 时也会发生这种情况,这似乎出乎您的意料,而且它也可能导致问题,因为 B 中的所有字段可能尚未初始化。因此,从非 final.

的构造函数调用任何方法是 bad practice

你的例子很好地证明了:

你说你期望第一个打印语句输出“A”,大多数人会期望输出“4”,但实际发生的是你得到一个“0”,因为字段 B.a 尚未初始化。


public A()
    {
        print();
    }

这里,print()不是静态方法,所以这是this.print()的缩写。即使您在 class A 的构造函数中,它也是作为 new B() 的一部分从 B 的构造函数中调用的,因此 this 是一个B 的实例(在 B 的构造函数尚未完全完成其工作的时间点)。