Java:调用超类的构造函数,调用设置子类字段的被覆盖方法



我有这个演示代码:

class Test2 extends Test {
    public int number = 0;
    @Override
    public void set(){
        number = 1;
        info();
    }
    @Override
    public void info(){
        System.out.println(number);
    }
}
public class Test {
    public Test(){
        set();
    }
    public void set(){
    }
    public void info(){
    }
    public static void main(String[] args){
        Test2 object = new Test2();
        object.info();
    }
}

代码给出以下输出:

1
0

为什么?我期望这个输出:

1
1

在我的opionion中,主函数调用Test2类的构造函数来创建一个对象。构造函数自动调用超类的构造函数。此构造函数调用被重写的方法set()。因此,类Test2的方法set()被调用。此方法设置字段并调用写数字的info()方法。然后,main函数再次调用所创建对象的info()方法。

数字字段被正确设置为第一行输出为"1"。但是为什么第二行包含0?这个领域似乎根本就没有设定。你能解释一下吗?

我应该怎么做才能得到我期望的行为?提前感谢!

class Test2 {
    public int number = 0;
}

相当于

class Test2 {
    public int number;
    public Test2() {
        super();
        number = 0;
    }
}

因此,通过调用超级构造函数,字段number被设置为1。从超级构造函数返回后,将执行number到0的赋值。

只需移除赋值,它就可以按照您的期望进行操作。

如果说Animal扩展了Dog,则调用动物a=新狗狗()

然后步骤顺序如下

  1. 动物静态场已初始化

  2. 动物的静态块被执行

  3. 狗的静态字段被初始化<它们将被重新初始化如果Animal在中更改了它们

  4. 狗的静态块被执行

  5. 动物的非静态场已初始化如果Animal在中更改了它们,则重新初始化

  6. 动物建造师执行

  7. 狗的非静态字段已初始化<如果动物改变了它们>

  8. Dog Constructor已执行

您的代码正在打破Java中的一条黄金法则——永远不要在构造函数中调用可以被子类覆盖的方法——也就是说,这些方法应该是私有的。

当Test2中的默认构造函数完成时,它已经覆盖了通过初始化器public int number = 0;分配给它的初始值1。

最新更新