class Fu{
int j = 1;
Fu(){super();this.draw();}
void draw(){System.out.println("j "+j);}
}
class Zi extends Fu{
int i = 2;
Zi(){super();draw();}
void draw(){System.out.println("i "+i);}
public static void main(String[] args){
Zi z = new Zi();
}
}结果是:  i 0
  i 2  第一个  i 0    哪来的呢 ?   望高手指点

解决方案 »

  1.   

    程序调用顺序为
    类Zi()中super(),然后是类Fu()中super(),此时初始化j=1,然后到Zi()中draw(),此时i,并没有初始化,默认为0,所以有输出i 0;子类对象的构造和初始化顺序总结为:
    1.分配成员变量的存储空间并进行默认的初始化;
    2.调用对象的构造函数,绑定构造函数的参数,所以初始化j=1;
    3.如果对象构造函数中存在this调用,则调用相应重载的构造函数,重载的构造函数执行完后,回到当前构造函数,当前构造函数执行第5步
      若没有this调用,执行步骤4;
    4.显式或隐式地调用父类的构造函数,一直到object为止,父类的构造函数又开始执行第2步流程,父类的构造函数执行完毕后回到当前构造
      函数继续执行;
    5.对成员变量进行显式初始化;
    6.执行构造函数中其它程序代码;
    7.如果有初始化块,优先执行初始化块程序;
      

  2.   

    在构造函数中不要调用菲final的方法,有可能会引发多态的未初始化,当然你这个不会。
      

  3.   

    再问一下:我怎么才能在Fu类中的构造函数中调用自己的draw()方法呢?
      

  4.   

    刚才看错了,从你的运行结果来看,尽管你加上了this但还是引发了多态
    解决方法不要再构造函数中调用被继承的方法,最好不要调用任何方法,仅仅完成初始化作用
      

  5.   

    如果构造的是Fu类的对象,则会调用自己的draw()方法。
      

  6.   

    好像,用super.draw();这种格式可以调用父类本身的方法。如果不对请高手指点
      

  7.   

    其实,这是一道关于Overriding(重写)的问题:当子类Method与父类的Method一样时,父类的不再起作用(有private,final修饰的Method除外)。
    从这一点在来看这道题就很容易了:
    子类构造方法首先调用父类构造方法——>
    父类构造方法调用this.draw()(此时的draw其实还是子类的draw(),Overriding的原因,由于父类field中无i值,故取默认值0)——>
    子类构造方法调用子类draw(),而子类field中能找到i=2。
    因此,输出结果i=0,i=2另外,你在父类的draw()前面加final或者private,就会得到j=1,i=2了。
      

  8.   

    补充一点,当你在子类中用super.draw()明确指明调用父类的方法的使用,才能真正使用Overriding(重写)后父类的方法。