我有这个演示代码:
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中,main函数调用Test2类的构造函数来创建一个对象。构造函数自动调用超类'构造函数。此构造函数调用被覆盖的方法set()。因此调用类Test2的方法set()。此方法设置字段并调用写入数字的info()方法。然后main函数再次调用创建对象的info()方法。
正确设置数字字段,因为第一行输出为“1”。但为什么第二行包含0?看来这个领域根本没有设定。你能解释一下吗?
我应该怎样做才能得到我期望的行为?提前谢谢!
答案 0 :(得分:17)
class Test2 {
public int number = 0;
}
相当于
class Test2 {
public int number;
public Test2() {
super();
number = 0;
}
}
因此,通过调用超级构造函数,字段number
设置为1.从超级构造函数返回后,执行number
到0的赋值。
只需删除作业,它就应该按照您的预期行事。
答案 1 :(得分:2)
如果说动物延伸狗,你打电话 动物a =新狗()
然后步骤顺序如下
动物静态字段已初始化
执行静态动物块
狗的静态场被初始化<他们将重新初始化 如果动物改变了它们>
执行静态阻止
动物的非静态场被初始化它们将是 如果Animal以任何方式更改它们,则重新初始化>
执行动物构造函数
初始化的狗的非静态场<如果,他们将重新初始化 动物改变了它们>
执行狗构造函数
答案 2 :(得分:1)
您的代码在Java中打破了一条黄金法则 - 永远不会在构造函数中调用可被子类覆盖的方法 - 即此类方法应该是私有的。
当Test2中的默认构造函数完成时,它已经覆盖了通过初始化程序public int number = 0;
分配给它的初始值1。