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

★如梦初醒☆

初级黑马

  • 黑马币:0

  • 帖子:9

  • 精华:0

© ★如梦初醒☆ 初级黑马   /  2012-4-24 19:27  /  2191 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

子类里面的每个构造函数里都有隐式的super(),为什么一定要有super()呢?

7 个回复

倒序浏览
本帖最后由 周海诚 于 2012-4-24 19:36 编辑

毕老师讲得很清楚!绿字是关键!
子类中定义的成员变量同名时,子类就隐藏了从父类继承的成员变量。
当子类中定义了一个方法。并且这个方法的名字、返回类型、参数个数和类型和父类的某个方法完全相同时,
子类从父类继承的这个方法将被隐藏如果在子类中想使用被隐藏的成员变量或方法就可以使用关键字super。

补充:那句没有父亲儿子怎么从石头里蹦出来就是最好的解释。
回复 使用道具 举报
因为子类要得到父类的非静态成员(方法 ,变量)因为静态成员在类装载时就赋予了子类 当子类初始化时如果不加这条语句的话 父类不能实例化 那么就得不到非静态成员了
回复 使用道具 举报
Super()会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();

为什么子类一定要访问父类中的构造函数。

因为父类中的数据子类可以直接获取,所以子类在建立对象时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
回复 使用道具 举报
子类中所有的构造函数默认都会访问父类中空参数的构造函数
因为每一个构造函数的第一行都有一条默认的语句super();
子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数;
super(...);用来调用父类的对应构造方法,this(...);用来调用本类中调用了父类构造方法的构造方法
回复 使用道具 举报
子类中所有的构造函数默认都会访问父类中空参数的构造函数
因为每一个构造函数的第一行都有一条默认的语句super();
子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数;
super(...);用来调用父类的对应构造方法,this(...);用来调用本类中调用了父类构造方法的构造方法
回复 使用道具 举报

子类里面的每个构造函数里都有隐式的super(),为什么一定要有super()呢?

super用来对父类构造函数的调用,子类在继承父类时,有些方法同父类相同就没必要覆写了,直接调用父类的方法就好了;但是如果没有super来访问父类的话,父类就不会被加载,父类构造函数就不能初始化,就不能调用父类的方法,也就是说内存里没有怎么掉调;
回复 使用道具 举报
本帖最后由 真真姐 于 2012-10-21 14:48 编辑

关于继承这是个大问题:要提到内存机制了,认真看看,后面还给你写了代码分析,是继承和super()大总结!

内存机制:父类和子类是占用同一块内存的,子类是依附于父类的,先有父类再有子类,只不过子类在父类的基础上增加了自己的方法和属性。
所以:   一个子类对象的产生,必须先调用父类的构造方法产生一个父类实例,然后在这个实例基础上添加子类自己的东西,但是没有父类的构造方法子类根本不可能有构造方法!
问题来了:你会问,我的父类就没有写构造方法,但是我的子类有写构造方法啊,各种有,有参的无参的都很正常啊,而且运行也很好啊,如下面的这个:
  1. public class Tet extends Text1{
  2.                 public Tet(){                    构造一
  3.              }
  4.                 public Tet(int a){             构造二,竟然还是有参的
  5.                  }
  6.                 public static void main(String[] args){
  7.                  }
  8.         }

  9. class Text1{
  10.         }  
复制代码
有这个疑问很正常!!   这就涉及到另一个知识点,构造方法!!
详解:
当每一个类建立的时候,系统都默认添加一个没有参数也没有方法体的构造函数,还记得吧!
所以父类中有构造方法,而且是系统默认存在的构造方法,所以你子类才可能建立构造方法!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
问题又来了:子类有无参的构造方法是合理的了,但是我还有有参的构造方法啊,怎么还正确!
  1. public class Tet extends Text1{
  2.                 public Tet(){
  3.                 //super();     // 正是系统默认提供的super();在起作用,正是默默的它,指向了父类默认存在的构造函数,所以你的代码才得以正确运行,都是它的功劳啊!!
  4.              }
  5.                 public Tet(int a){
  6.                 //super();    // 正是系统默认提供的super();在起作用,正是默默的它,指向了父类默认存在的构造函数,所以你的代码才得以正确运行,都是它的功劳啊!!
  7.                                  //在这里我们给它一首赞歌
  8.                  }              //啊!是它在内存中给了子类一个机会,子类才得以自由实例化,啊!是它悄悄地藏在这里,你不知不觉!啊!是它.... 好了够了啊!
  9.                 public static void main(String[] args){
  10.                  }
  11.         }

  12. class Text1{         
  13.         }
复制代码
当你吧某个子类的构造函数里面写成super(100)等的时候,你就会发现出错了,就是这个道理,因为父类默认的构造函数是没有参数的!
问题又来了:只能说小伙很有思想啊,下面的代码又出错了,认真看看!
  1. public class Tet extends Text1{
  2.                 public Tet(){                    // 这里为什么会报错呢,父类不给面子了吗??? 我们的super()呢,刚才还为你唱歌,这会怎么不起作用了!!你陷入了疑问。。。。
  3.              }
  4.                 public Tet(int a){             // 这里为什么会报错呢,父类不给面子了吗??? 我们的super() 呢,刚才还为你唱歌,这会怎么不起作用了!!你陷入了疑问 。。。。
  5.                  }
  6.                 public static void main(String[] args){
  7.                  }
  8.         }

  9. class Text1{
  10.         public Text1(int a){       //  原来父类大哥,刚才自己努力了一把,这有了一个有参的构造函数!!
  11.          }
  12.         }
复制代码
这是问什么呢??,这就是因为,系统给子类构造函数默认的super(),找不到父类的无参的构造函数了,
问题又来了:为什么找不到了呢!他不是默认的吗!!
现在父类已经变身了没看到吗,已经有了人自己的有参构造方法了,系统不提供默认的构造方法了,有了自己的房子还想住国家的公租房?开玩笑吧!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
问题又来了:那现在怎么办呢?如何能正常编译呢
这里提供两种方法
A、子类构造方法中全部自定义为有参super, 就像super(100)调用父类存在的带参数的构造方法!
B、父类中重新定义无参的构造方法,   public Text1(){      方法体可以根据需要取舍!
                                                                        };

没接触过super的童鞋到这也该理解了吧!到这里是不是已经完美解决这个问题了呢,完全手工,耗时不少,倾注笔者不少感情,求置顶,求加精!给分给分了!




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