我有这个演示代码:
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=新狗狗()
然后步骤顺序如下
-
动物静态场已初始化
-
动物的静态块被执行
-
狗的静态字段被初始化<它们将被重新初始化如果Animal在中更改了它们
-
狗的静态块被执行
-
动物的非静态场已初始化如果Animal在中更改了它们,则重新初始化
-
动物建造师执行
-
狗的非静态字段已初始化<如果动物改变了它们>
-
Dog Constructor已执行
您的代码正在打破Java中的一条黄金法则——永远不要在构造函数中调用可以被子类覆盖的方法——也就是说,这些方法应该是私有的。
当Test2中的默认构造函数完成时,它已经覆盖了通过初始化器public int number = 0;
分配给它的初始值1。