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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 聖手`书生 中级黑马   /  2013-4-4 10:15  /  1596 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

代码中的执行结果有些迷惑,执行结果如截图,主函数并没有调用Zi(),为什么会执行了它,然后因为父类的构造函数有两个,为什么默认执行了Fu(),不是说默认在子类构造函数第一行执行的是父类空参数的构造函数吗。这两个问题不解,结果也出乎意料。
  1. class Fu //extends Object
  2. {
  3.         int num ;
  4.         Fu()
  5.         {
  6.                 //super();
  7.                 num= 60;
  8.                 System.out.println("fu run");
  9.         }
  10.         Fu(int  x)
  11.         {
  12.                 System.out.println("fu ...."+x);
  13.         }
  14.        
  15. }

  16. class Zi extends Fu
  17. {
  18.         Zi()
  19.         {
  20.                
  21.                 //super();  
  22.                 //super(4);
  23.                 System.out.println("zi run");
  24.         }
  25.         Zi(int x)
  26.         {
  27.                 this();
  28.                 //super();
  29.                 //super(3);
  30.                 System.out.println("zi..."+x);
  31.         }
  32. }

  33. class  ExtendsDemo4
  34. {
  35.         public static void main(String[] args)
  36.         {
  37.                 Zi z = new Zi(0);
  38.                 System.out.println(z.num);
  39.         }
  40. }
复制代码

99999.jpg (9.14 KB, 下载次数: 39)

99999.jpg

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

6 个回复

倒序浏览
  1. class Fu //extends Object
  2. {
  3.         int num ;
  4.         Fu()   //因为这里有无参构造函数 所以执行它 打印结果为 fu run   第二步
  5.         {
  6.                 //super();
  7.                 num= 60;
  8.                 System.out.println("fu run");
  9.         }
  10.         Fu(int  x)
  11.         {
  12.                 System.out.println("fu ...."+x);
  13.         }
  14.         
  15. }

  16. class Zi extends Fu
  17. {
  18.         Zi()  
  19.         {
  20.                
  21.                 //super();   这里你也注释了,默认在子类构造函数第一行有个调用父类无参构造函数: 第一步
  22.                 //super(4);
  23.                 System.out.println("zi run");
  24.         }
  25.         Zi(int x)  //  被调用 打印结果为 Zi...0  第四步
  26.         {
  27.                 this();
  28.                 //super();
  29.                 //super(3);
  30.                 System.out.println("zi..."+x);
  31.         }
  32. }

  33. class  ExtendsDemo4
  34. {
  35.         public static void main(String[] args)
  36.         {
  37.                 Zi z = new Zi(0); //new Zi(0) 创建了有参数的子类对象,进行初始化,调用子类有参构造函数  第三步
  38.                 System.out.println(z.num);   
  39.         }
  40. }
复制代码
/*
* 对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,
* 当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,
* 父类的非静态代码块执行完毕,接着执行父类的构造方法;
* 父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。
* 子类的非静态代码块执行完毕再去执行子类的构造方法。
* 总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。

注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
*/

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
class Fu //extends Object
{
        int num ;
        Fu()
        {
                //super();
                num= 60;
                System.out.println("fu run");
        }
        Fu(int  x)
        {
                System.out.println("fu ...."+x);
        }
        
}

class Zi extends Fu
{
        Zi()
        {
               
                //super();  
                //super(4);
                System.out.println("zi run");
        }
        Zi(int x)
        {
                this();
                //super();
                //super(3);
                System.out.println("zi..."+x);
        }
}

class  ExtendsDemo4
{
        public static void main(String[] args)
        {
                Zi z = new Zi(0);
                System.out.println(z.num);
        }
}

当代码执行到  Zi z = new Zi(0);是因为 new Zi(0)是带参数的所以会执行Zi类中的带参构造方法
Zi(int x)  //  被调用 打印结果为 Zi...0  第四步
        {
                this();
                //super();
                //super(3);
                System.out.println("zi..."+x);
        }
又因为带参zi构造方法中有this();那么就不会产生默认的super(),这时就会调用zi中不带参数的构造方法
Zi()  
        {
               
                //super();   这里你也注释了,默认在子类构造函数第一行有个调用父类无参构造函数: 第一步
                //super(4);
                System.out.println("zi run");
        }
这个构造方法中是有默认的super()就会调用Fu类中的不带参数构造方法来完成父类的初始化。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
创建子类对象的时候,首先默认调用父类的无参构造方法,所以首先是fu run,
然后因为是new zi(0),所以调用子类的有参构造方法,你在有参构造里又调用了子类的无参构造(this()),所以,出现zi run,
执行完无参构造方法,又回到有参构造里执行打印的代码。
而后你调用变量num,子类中是没有的,所以实际上是用的继承自父类的num

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
若还有问题,继续追问; 没有的话,尽量及时将帖子分类改成【已解决】~
回复 使用道具 举报
Zi(){  }里面第一句有一个隐式的super();   这个就等价于Fu();
顺序:
Zi(int x)    ->     Zi()   ->   Fu()                最后执行main()中的是 System.out.println(z.num);   //输出的是在Fu()中已经将num改为60的结果。
回复 使用道具 举报
本帖最后由 王梦南 于 2013-4-6 14:41 编辑
  1. class Fu //extends Object
  2. {
  3.         int num ;
  4.         Fu()
  5.         {
  6.                 //super();
  7.                 num= 60;
  8.                 System.out.println("fu run");
  9.         }
  10.         Fu(int  x)
  11.         {
  12.                 System.out.println("fu ...."+x);
  13.         }
  14.         
  15. }

  16. class Zi extends Fu
  17. {
  18.         Zi()//创建子类对象,会先调用父类构造函数。没有显示写出调用父类哪个构造方法,默认调用无参的
  19.         {
  20.                
  21.                 //super();  
  22.                 //super(4);
  23.                 System.out.println("zi run");
  24.         }
  25.         Zi(int x)
  26.         {
  27.                 this();//this()是调用子类的无参构造方法,如果想调用父类无参构造函数应该用super();
  28.                 //super();
  29.                 //super(3);
  30.                 System.out.println("zi..."+x);
  31.         }
  32. }

  33. class  ExtendsDemo4
  34. {
  35.         public static void main(String[] args)
  36.         {
  37.                 Zi z = new Zi(0);//初始化子类,调用子类1个参数的构造方法
  38.                 System.out.println(z.num);
  39.         }
  40. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 新人加油~

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马