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,得到结果为“初始化”
请问是怎么回事?请各位给个比较详细的解释

解决方案 »

  1.   

    复杂对象的构造方法调用过程:
    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次