日期:2014-05-20  浏览次数:20587 次

这个含内部类的程序,运行结果为什么是这样的?

class Egg2 {
protected class Yolk {
public Yolk()  {System.out.println("Egg2.Yolk()");}
    public void f()  {System.out.println("Egg2.yolk.f()");}
}
private Yolk y=new Yolk();
public Egg2()  {System.out.println("New Egg2()");}
public void insertYolk(Yolk yy)  {y=yy;}
public void g()  {y.f();}
  }
  
    public class BigEgg2 extends Egg2 {
        public class Yolk extends Egg2.Yolk{
         public Yolk()  { System.out.println("BigEgg2.Yolk()");}
         public void f() { System.out.println("BigEgg2.Yolk.f()"); }
        }
         public BigEgg2()  {   insertYolk (new Yolk());  }
         public static void main(String[] args)  {
          Egg2 e2=new BigEgg2();
          e2.g();         
         }   
        }
 
这代码是thinking in java里的。第213页。我看不懂运行结果。为什么输出的顺序是这样的呢?
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
出现了两个Egg2.Yolk。第一个是不是在初始化静态变量 y 时出现的呢?第二个是不是在初始化BigEgg2构造器时才出现的?
还有,最后怎么还冒出一个BigEgg2.Yolk()?e2不是只调用了g()吗。
这程序真的看不明白……

------解决方案--------------------
编程思想里的代码都是这样,虽然很短,但是很绕,这个debug自己调试下吧,就知道执行顺序了
------解决方案--------------------
首先,要理解内部类和类没有什么区别。
其次,来说说这个顺序,先设BigEgg2为B,Egg2为B,然后继承自A,main中new B,那么首先在初始化B之前会
初始化A,A的域y被初始化,所以首先打印出Egg2.Yolk(),然后执行构造函数,打印出New Egg2(),接下来是父类初始化
首先没有域,所以构造函数被执行,使用父类方法 insertYolk ,然后B的内部类被初始化,还是遵从前面的述说,所以先打印
Egg2.yolk,然后执行自己的构造函数,最后一个打印是由于子类重写了父类的g方法,所以是如此结果,是Java多态的一种表现---
重写方法。
最后,个人觉得,《Java编程思想》对于初学者比较吃力,有些深度,且有很多的经验之谈。可以看一些更加简单的书籍。