A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 姚宏 中级黑马   /  2013-11-26 10:54  /  1282 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class  Egg
  2. {
  3.         protected class Yolk{
  4.                 public Yolk(){
  5.                         System.out.println("Egg.Yolk()");
  6.                 }
  7.                 public void f(){
  8.                         System.out.println("Egg.Yolk.f()");
  9.                 }
  10.         }
  11.         private Yolk y=new Yolk();
  12.         public Egg(){
  13.                 System.out.println("New Egg()");
  14.                
  15.         }
  16.         public void insertYolk(Yolk yy){
  17.                 y=yy;
  18.         }
  19.         public void g(){
  20.                 y.f();
  21.         }
  22. }
  23. public class BigEgg extends Egg{
  24.    public class Yolk  extends Egg.Yolk{
  25.            public Yolk(){
  26.                    System.out.println("BigEgg.Yolk()");
  27.            }
  28.            public void  f(){
  29.                    System.out.println("BigEgg.f()");
  30.            }
  31.    }
  32.    public BigEgg(){
  33.            insertYolk(new Yolk());
  34.    }

  35.         public static void main(String[] args) {
  36.                 // TODO Auto-generated method stub
  37.             Egg e=new BigEgg();
  38.             e.g();
  39.         }

  40. }
复制代码
是这样的,书上看到一个例子,分析不出来了
运行结果是:Egg.Yolk()
New Egg()
Egg.Yolk()
BigEgg.Yolk()
BigEgg.f()

评分

参与人数 1技术分 +1 黑马币 +5 收起 理由
枫儿 + 1 + 5 神马都是浮云

查看全部评分

3 个回复

倒序浏览
本帖最后由 freehiker 于 2013-11-26 13:03 编辑

我标记了一下执行顺序,先写上代码,然后我再一步步说明
  1. package test.java;

  2. class  Egg
  3. {
  4.         protected class Yolk{
  5.                 public Yolk(){
  6.                         System.out.println("Egg.Yolk()"); // -> 1-1:Egg.Yolk(); 2-1-1:Egg.Yolk();
  7.                 }
  8.                 public void f(){
  9.                         System.out.println("Egg.Yolk.f()");
  10.                 }
  11.         }
  12.         private Yolk y=new Yolk(); // -> 1-1
  13.         public Egg(){
  14.                 System.out.println("New Egg()"); //->1-2.New Egg()
  15.                
  16.         }
  17.         public void insertYolk(Yolk yy){
  18.                 y=yy;
  19.         }
  20.         public void g(){
  21.                 y.f();
  22.         }
  23. }
  24. public class BigEgg extends Egg{
  25.    public class Yolk  extends Egg.Yolk{
  26.            public Yolk(){
  27.                    //super(); -> 2-1
  28.                    System.out.println("BigEgg.Yolk()"); // 2-1-2:BigEgg.Yolk();
  29.            }
  30.            public void  f(){
  31.                    System.out.println("BigEgg.f()"); // 3-1:BigEgg.f 因为Egg.Yolk下的f方法被覆盖
  32.            }
  33.    }
  34.    public BigEgg(){
  35.            //super();  -> 1
  36.            insertYolk(new Yolk()); // -> 2
  37.    }

  38.         public static void main(String[] args) {
  39.                 // TODO Auto-generated method stub
  40.             Egg e=new BigEgg();
  41.             e.g(); //-> 3
  42.         }

  43. }
复制代码

/*
* 1.创建BigEgg()对象,BigEgg()的构造函数中隐含super(),所以会执行Egg()的构造代码,即先初始化Egg对象
* 2.初始化Egg对象时,先要初始化成员变量,即Yolk y=new Yolk();所以这时候就会输出"Egg.Yolk()"
* 3.接着通过Egg构造函数继续初始化Egg对象,这时就输出了"New Egg()";
* 4.执行insertYolk(new Yolk());语句,这里要初始化BigEgg.Yolk对象
* 5.和上面同样的道理,输出了父类构造函数中的"Egg.Yolk()"字符串
* 6.继续执行System.out.println("BigEgg.Yolk()");输出了BigEgg.Yolk()字符串
* 7.继续执行e.g(),因为BigEgg中没有g方法
* ,所以调用Egg中的g方法,此方法继续调用Egg.Yolk的f方法,因为Egg.Yolk的f方法被BiggEgg
* .Yolk的f方法覆盖,所以输出BigEgg.f()字符串
*/

回复 使用道具 举报
首先,先从主函数开始分析,主函数进入栈内存

主函数先执行new BigEgg();这时便找到对应的类加载进方法区中,由于BigEgg继承了Egg类,因此在方法区中首先加载进来的是Egg类

Egg在加载的过程中会执行到这句private Yolk y=new Yolk();,接着便在堆内存中创建new Yolk()对象并且对应的构造函数也就进栈了,

这时就输出Egg.Yolk()了,Yolk构造函数出栈,new Yolk()对象赋给Yolk类的引用y,private Yolk y=new Yolk();执行完毕。

然后BigEgg类加载进方法区中,BigEgg类构造函数进栈,由于BigEgg类继承了Egg类因此BigEgg类中有了Egg类中的super引用,

并且在BigEgg类构造函数中的第一句执行super(),父类构造函数进栈,对Egg的子类进行初始化动作,这时便输出了New Egg()这句话,父类构造函数出栈,进行子类显示初始化,执行insertYolk(new Yolk());,在堆中再次创建new Yolk()对象并且对应的构造函数也就进栈了,此时在的Yolk类对象是Egg类中的内部类,并且继承了Egg中的Yolk类,和上面的分析一样,输出Egg.Yolk()后输出BigEgg.Yolk();最后执行e.g();输出BigEgg.f()
回复 使用道具 举报
帅气 问题解决了两位 谢谢了  当时就是对内部类父类构造方法在子类中的疑问纠结
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马