在Egg2 e2 = new BigEgg2();的时间调用父类的构建器,但父类有一个成员变量private Yolk y = new Yolk();
这个时间构造new Yolk(),所以调用
public Yolk() 
{
     System.out.println("Egg2.Yolk()");
}
而后调用父类的构建器
  public Egg2() {
    System.out.println("new Egg2()");
  }
而后 insertYolk(new Yolk());
再调用一次
public Yolk() 
{
     System.out.println("Egg2.Yolk()");
}以下的我想你也明白我就不多说了

解决方案 »

  1.   

    以下是一个总结在创建对象时,对象所在类的所有数据成员会首先进行初始化,如果其中的成员变量有对象,那么它们也会按照顺序执行初始化工作。在所有类成员初始化完成后,才调用对象所在类的构造方法创建对象。构造方法作用就是初始化。
    静态对象(变量)在非静态对象前初始化。静态对象(变量)只初始化一次,再次调用就不初始化了,但非静态对象在每次调用时都要初始化。
    程序中的主类的静态变量会在main()方法执行前进行初始化工作。
    不仅第1次创建对象时,类中所有的静态变量要初始化,第1次访问类中的静态变量(没有创建对象)时,该类中所有的静态变量也要按照它们在类中排列的顺序初始化。
    初始化的顺序包括构造方法调用的顺序如下:
    1. 主类的静态成员首先初始化。
    2. 主类的超类的构造方法按照从最高到最低的顺序被调用。
    3. 主类的非静态对象(变量)初始化。
    4. 调用主类的构造方法。
    在一个构造方法中只能调用一次其它的构造方法,并且调用构造方法的语句必须是第一条语句。
      

  2.   

    谢谢weimenren(愚人碼頭)
    我已知道是怎么回事了,不过你好像说得不是很完整---就是Yolk()会被调用两次,完整过程如下:执行java BigEgg2
    装载 class BigEgg2 and Egg2
    执行 "Egg2 e2 = new BigEgg2();" 要调用Egg2的Constructor 先初始化变量即 private Yolk y =  new Yolk();因此执行Egg2中的Yolk的Constructor产生"Egg2.Yolk()"的输出.再执行Egg2的Constructor产生"New Egg2"输出.调用BigEgg2的Constructor,其中有"new Yolk",执行BigEgg2中Yolk的Constructor,由于其继承自Egg2.Yolk,先执行Egg2.Yolk(),再执BigEgg2.Yolk(),产生两个输出"Egg2.Yolk() BigEgg2.Yolk()" 产生的BigEgg2.Yolk向上转型,即 "y=yy".
    执行"e2.g()",g(){y.f();},即调用Yolk的f()方法.由于多态,y.f() 执行的应是BigEgg2.Yolk 中的f()(它覆写了Egg2.Yolk.f()).产生"BigEgg2.Yolk.f()"的输出
    结果应是:
    Egg2.Yolk()
    New Egg2()
    Egg2.Yolk()
    BigEgg2.Yolk()
    BigEgg2.Yolk.f()