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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 谭荣强 高级黑马   /  2014-4-14 10:39  /  1985 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

这玩意麻烦,看了忘,忘了看,看了又出现新问题。 子类的无参构造方法还需要手动调用父类的构造方法吗,zi(int x){}调用一次还不够吗,又没调用这个zi(){};不加还编译不过。帮忙看下啊,各位。
class fu
{       
        fu(int str)
        {
                System.out.println("fu run");
        }
}

class zi extends fu
{
        zi()
        {
                //super(5);此语句不可少,为什么
                System.out.println("zi run");       
        }
        zi(int x)
        {       
                super(5);                 
                System.out.println("zi....+4");
        }
}
class lianxi
{
        public static void main(String[] args)
        {
        //        zi z = new zi();
                zi z1 = new zi(4);          
        }
}

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

14 个回复

倒序浏览
建议楼主再复习一下【构造函数的调用】 和 【函数的重载】 这两部分


class zi extends fu
{
        zi()
        {
                //super(5);      // 这一句不能少,构造函数里子类调用父类必须用 super 来调用                          System.out.println("zi run");        
        }
        zi(int x)     //  zi() 和 zi(int x) 是重载,这句调用了 super 跟上句没关系,各用各的。
        {        
                super(5);                 
                System.out.println("zi....+4");
        }
}


评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

回复 使用道具 举报
一点想法:
    子类的构造过程中,必须 调用其父类的构造方法。实现如下:
1、super(); 默认调用父类无参数的构造方法。可以省略。(父类没写构造方法,系统加上默认无参构造方法)
2、super(参数列表);来调用父类有参数的构造函数。不可以省略。

如上例,父类中没有默认无参的构造方法,子类中必须有super(参数列表);调用父类有参构造函数。否则编译出错。

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
这个问题其实是这样的,如果子类没有显式调用父类的构造函数的时候,就会默认的调用他的不带参数的构造函数,
你这个代码就会变成这样



  1. class fu
  2. {
  3.         fu(int str)
  4.         {
  5.                 System.out.println("fu run");
  6.         }
  7. }

  8. class zi extends fu
  9. {
  10.         zi()
  11.         {
  12.                     super();//如果不调用父类构造方法,此句是默认的,也就是如果你不写,也会默认出现。但恰恰父类没有无参的构造方法,所以出错了
  13.                 //super(5);//此语句不可少,为什么
  14.                 System.out.println("zi run");        
  15.         }
  16.         zi(int x)
  17.         {        
  18.                 super(5);                 
  19.                 System.out.println("zi....+4");
  20.         }
  21. }
  22. public class lianxi
  23. {
  24.         public static void main(String[] args)
  25.         {
  26.         //        zi z = new zi();
  27.                 zi z1 = new zi(4);         
  28.         }
  29. }
复制代码

super();//如果不调用父类构造方法,此句是默认的,也就是如果你不写,也会默认出现。但恰恰父类没有无参的构造方法,所以出错了

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

回复 使用道具 举报
所以将你的父类添加无参构造方法就可以省略写super语句。但编译器还是会默认加上这一句的。


  1. class fu
  2. {
  3.                 fu(){}
  4.         fu(int str)
  5.         {
  6.                 System.out.println("fu run");
  7.         }
  8. }

  9. class zi extends fu
  10. {
  11.         zi()
  12.         {
  13.                     //super();如果不调用父类构造方法,此句是默认的,也就是如果你不写,也会默认出现。但恰恰父类没有无参的构造方法,所以出错了
  14.                 //super(5);//此语句不可少,为什么
  15.                 System.out.println("zi run");        
  16.         }
  17.         zi(int x)
  18.         {        
  19.                 super(5);                 
  20.                 System.out.println("zi....+4");
  21.         }
  22. }
  23. public class lianxi
  24. {
  25.         public static void main(String[] args)
  26.         {
  27.         //        zi z = new zi();
  28.                 zi z1 = new zi(4);         
  29.         }
  30. }
复制代码


评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
构造函数调用过程是这样:
1.如果一个类不写构造函数,会默认生成一个空参数的的构造函数:类名()。如果写了构造函数,而且这些构造函数中没有空参数的,就不会给你默认加这个类名(),就是没有类名()这个构造函数。
2.子类的构造函数中会隐式的加个super(),这句默认在构造函数第一行。也就是会隐式调用父类的空参数构造函数,如果父类没有空参数的构造函数,就要手动用super(参数)来指定一个父类的构造函数。不然会报错。
3.给你扩展一下,当子类的构造函数第一行写了this()调用本类的其他构造函数时,那个隐式的super()就没有了,因为不能两个都在第一行。不过可以肯定的是你子类中总有一个或多个构造函数会调用super(),就是没有this()的那些。

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

回复 使用道具 举报
ithmC4 发表于 2014-4-14 11:24
构造函数调用过程是这样:
1.如果一个类不写构造函数,会默认生成一个空参数的的构造函数:类名()。如果写 ...

不对啊,哥们           第一行写了this()调用本类的其他构造函数时,那个隐式的super()就没有了

这句话不对。。super()调用的始终存在啊,怎么会没有呢。。:L是在调用的其他构造函数的第一句吧,这不还是在第一句吗。。。
回复 使用道具 举报
ithmC4 中级黑马 2014-4-14 11:49:09
8#
对啊 ,我最后一句就是这个意思
回复 使用道具 举报
明白了,偶偶
回复 使用道具 举报
wangkerui 发表于 2014-4-14 10:52
建议楼主再复习一下【构造函数的调用】 和 【函数的重载】 这两部分

又看见你了:lol
回复 使用道具 举报
本帖最后由 ilvsoft 于 2014-4-14 12:10 编辑

zi()
        {
                //super(5);此语句不可少,为什么
                System.out.println("zi run");        
        }

因为你对子类无参数构造函数重写了,那么只要是子类构造函数那么他的第一行一般一定是默认的super();但是你对父类的构造函数重写了,那么这个时候就必须得手动写你子类构造函数要调用父类哪个构造函数了

总结只要是子类那么它的所有构造函数都会第一行调用父类的构造函数super(),如果父类的构造函数被重写了,那么这个时候必须在子类的构造函数第一行手动加上要调用的父类构造函数,也许这个时候你想到如果父类是抽象类这个时候还会写父类构造函数吗,答案是肯定的,因为构造函数式用来初始化的,虽然抽象父类不能被实例化但是我们只是用它的构造函数初始化而已,而只有new的时候才会返回一个对象,所以和这个抽象类不能被实例化一点不矛盾

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
子类构造函数第一行默认的有一个super(),你的事例中父类中的默认的构造函数已经没有了,因为你显示重新写了一个带参数的构造函数,这是子类的构造函数中必须显示的写明构造函数!
回复 使用道具 举报
通俗的理解就是,假如 动物-熊-熊猫是从下到上的集成关系,你创建了一个熊猫的对象,可以说多了一个熊,也可以说多了一个动物,所以动物和熊的构造函数都要执行。动物的构造函数在熊的构造函数中隐式的执行,熊的构造函数在熊猫的构造函数中隐式的执行,也就是说在熊猫的构造函数中,隐式的执行了熊和动物的构造函数,只不过动物的构造函数在隐式的熊的构造函数里面而已。
怎么样,绕晕了吧

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
解释的很详细啊!我也学习了!赞一下
回复 使用道具 举报
这个是构造方法的继承
构造方法可以是隐式的或者显式定义的,子类是否必须是显式的定义构造方法分为以下几种情况。
1、若父类没有显式的定义构造方法,子类可以定义也可以不定义构造方法,构造子类对象时会通过子类的构造方法来调用父类默认的构造方法。
2、若父类显式的定义了无参的构造方法,子类可定义也可不定义构造就去,构造子类对象时会通过子类的构造方法来调用父类无参的构造方法。
3、若父类仅定义了带参数的构造,则子类必须定义构造方法,并且必须在子类构造方法的第一行显式地(通过super)调用超类的构造 ,当超类重载构造方法时,必须为super()提供合适的构造参数。
如果在子类构造方法中没有通过super调用超类的构造方法。这是并不是不调用超类的构造方法,而是隐式地调用超类无参的构造方法,如果父类没有无参的构造方法,则编译错误。
还可以在父类中加个无参的构造方法。
  1. class fu
  2. {      
  3.             public fu()
  4.                         {
  5.                         }
  6.         fu(int str)
  7.         {
  8.                 System.out.println("fu run");
  9.         }
  10. }
  11. class zi extends fu
  12. {
  13.         zi()
  14.         {
  15.                // super(5);
  16.                 System.out.println("zi run");        
  17.         }
  18.         zi(int x)
  19.         {        
  20.                 super(5);                 
  21.                 System.out.println("zi....+4");
  22.         }
  23. }
  24. public class lianxi
  25. {
  26.         public static void main(String[] args)
  27.         {
  28.         //        zi z = new zi();
  29.                 zi z1 = new zi(4);         
  30.         }
  31. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

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