package net.greathack.string;
public class Test { public Test(){
setAa();
}
protected void setAa(){
}
}package net.greathack.string;
public class Test1 extends Test { private String aa="初始化";
public Test1(){
super();
}
protected void setAa(){
super.setAa();
aa="赋值后";
}
public String getAa(){
return aa;
}
public static void main(String[] args) {
Test1 test1 =new Test1();
System.out.print(test1.getAa());
}
}其中,Text1继承了Text
运行Text1,得到结果为“初始化”
请问是怎么回事?请各位给个比较详细的解释
public class Test { public Test(){
setAa();
}
protected void setAa(){
}
}package net.greathack.string;
public class Test1 extends Test { private String aa="初始化";
public Test1(){
super();
}
protected void setAa(){
super.setAa();
aa="赋值后";
}
public String getAa(){
return aa;
}
public static void main(String[] args) {
Test1 test1 =new Test1();
System.out.print(test1.getAa());
}
}其中,Text1继承了Text
运行Text1,得到结果为“初始化”
请问是怎么回事?请各位给个比较详细的解释
1、调用父类构造方法,重复直到最上层的父类,通常是Object类为止
2、根据各个成员的声明顺序,调用各个成员的初始化设定
3、执行子类自身的构造方法。我的理解是这样的:
Test1 test1 =new Test1();1、Test1的构造方法执行,调用父类Test的构造方法。
2、在父类的构造方法中调用的setAa(),相当于this.setAa(),在这里this是引用Test1对象的(根据多态性和RTTI),所以调用的是Test1类定义的setAa()方法。
3、Test1的setAa方法中调用父类setAa方法,由于是空方法所以没有影响,
下面执行aa ="赋值后"; 此时aa确实为“赋值后” 但这一句是在父类构造方法的执行过程中调用的,然后从构造方法返回后,又执行定义aa处的初始化,把aa恢复到“初始化”。
4、而Test1类自己的构造方法中又没有改变aa的值,所以最终aa是“初始化”。总结:由于没有认识到对象构造过程的正确顺序,所以aa被赋值了2次