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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何超 中级黑马   /  2013-11-6 16:27  /  2427 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class Super
  2. {
  3.         int i=0;
  4.         public Super(String S)
  5.         {
  6.                 i=1;
  7.         }
  8. }
  9. class Demo extends Super
  10. {
  11.         public Demo(String s)
  12.         {
  13.                 i=2;
  14.         }
  15.         public static void main(String[] args)
  16.         {
  17.                 Demo d=new Demo("yes");
  18.                 System.out.println(d.i);
  19.         }
  20. }
复制代码
这是毕老师的视频里的  有些疑问所以问下大家
这个代码错误  因为父类中缺少空参数的构造函数。
或者子类应该通过spuer语句指定要调用的父类中的构造函数。

我所知道的子类和父类的构造函数是这样的
如果父类没有定义任何构造函数则系统默认一个super(){},如果有任何一个自定义的构造函数则系统不会再默认。
运行子类的时候首先要运行父类的构造方法   

然后对于代码我所不理解的是
① 父类中有public Super(String S) 创建子类对象的时候运行父类构造函数不是可以运行 public Super(String S)么  
为什么一定要加一个 Super(){}才行
②如果按照毕老师的第二个解释 //或者子类应该通过spuer语句指定要调用的父类中的构造函数。此时修改的代码是不是这样
        public Demo(String s)
        {
                Super(String s);
                i=2;
        }  
③如果是按照②中毕老师所说的方法 那么 yes的赋值过程是怎样的

评分

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

查看全部评分

11 个回复

倒序浏览
首先Demo和Super中都没有String的构造函数,Demo d=new Demo("yes");是错误的,要么调用父类的,要么调用自己的
  1. class Super
  2. {
  3.         int i=0;
  4.         String s;
  5.         public Super(String s)
  6.         {
  7.                 this.s=s;
  8.                 i=1;
  9.         }
  10. }
  11. class Demo extends Super
  12. {
  13.         public Demo(String s)
  14.         {
  15.                 super(s);
  16.                 i=2;
  17.         }
  18.         public static void main(String[] args)
  19.         {
  20.                 Demo d=new Demo("yes");
  21.                 System.out.println(d.i);
  22.         }
  23. }
复制代码
回复 使用道具 举报
可以按照第二种方式调用父类构造函数。但是你格式写错了,调用父类含参构造函数只要用:super(变量);             就行了。因为调用父类的子类构造函数已经指定了参数类型String。
谢谢
回复 使用道具 举报
麦者 发表于 2013-11-6 16:49
首先Demo和Super中都没有String的构造函数,Demo d=new Demo("yes");是错误的,要么调用父类的,要么调用自 ...
  1. public Super(String s)
  2.         {
  3.                 this.s=s;
  4.                 i=1;
  5.         }
复制代码
  1. public Demo(String s)
  2.         {
  3.                 super(s);
  4.                 i=2;
  5.         }
复制代码
不是String构造函数么!!!没明白你的意思!

评分

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

查看全部评分

回复 使用道具 举报
Clare0621 发表于 2013-11-6 16:52
可以按照第二种方式调用父类构造函数。但是你格式写错了,调用父类含参构造函数只要用:super(变量);      ...

我就是很奇怪子父类中都有public 类名(String s)的构造函数啊
为什么 Demo d=new Demo("yes") 不能运行
回复 使用道具 举报
何超 发表于 2013-11-6 17:08
我就是很奇怪子父类中都有public 类名(String s)的构造函数啊
为什么 Demo d=new Demo("yes") 不能运 ...

this.s=s;   语句缺失
回复 使用道具 举报
好像你没有理解那个隐藏的super()和访问过程。
还有你想怎么改?
一、你想输出子类中i=2就:在父类中加个空参数构造函数:public Super(){}

二、访问父类就在子类构造函数中加super(s);
回复 使用道具 举报
子类继承父类,子类写了构造方法的话,实例化子类的时候会先调用父类的无参数的构造方法。
想当于,
public class Super{
    //如果我们没有写构造方法,系统默认有一个无参数的构造方法。
    //如果我们写了有参数的构造方法,就会覆盖无参的构造方法。
    //实例化子类的时候,如果没有手动调用父类的构造方法,则会默认调用父类的无参数的构造方法,如果父类没有无参的构造方法,程序则会报错。

}

public class Demo extends Super{
        public Dem0(){

}
}
回复 使用道具 举报
我们写类的时候,如果我们没有写构造方法,系统默认有一个无参数的构造方法。
如果我们写了有参数的构造方法,就会覆盖无参的构造方法。
子类继承父类,实例化子类的时候会先调用父类的构造方法,(就好像,儿子生出来之前,老爸要先生出来一样,哈哈)如果父类有无参的方法,则默认调用父类的无参的构造方法。
如果父类没有无参的构造方法,程序则会报错。
public class Demo extends Super{
        public Dem0(){//构造方法,
          Super();//如果我们没有手动调用父类的构造方法,会有这样一句默认的构造方法。可以删掉不写
          Super(参数);//如果父类只有一个有参的方法,子类必须手动调用父类的构造方法。
       }
}

自己整理了一下思路,希望你看了能理解一点。
回复 使用道具 举报
1.如果子类非要运行父类中的public Super(String S),那么子类构造函数 中就要明写一个这样的构造函数:super(String s),但是本题子类中没有写  。 2.不是的,super应该全部字母小写 3.“yes”先通过子类的s找到父类中构造函数的s,赋给该父类中构造函数的s, 此时s的值就是“yes”了,也就是说子类对象中就有“yes”地址值了。子类可  以对“yes”开始进行操作。
回复 使用道具 举报
本帖最后由 魏-玉-彪 于 2013-11-6 22:54 编辑
  1. package java131106;


  2. class Super
  3. {
  4.                              Super(){}  //方案1, 为父类加上无参构造,子类将自动调用
  5.         
  6.         
  7.         int i=0;
  8.         public Super(String S) //因为这里定义了有参构造,所以系统将不再给出无参构造
  9.         {
  10.                 i=1;
  11.         }
  12. }
  13. class Demo extends Super
  14. {
  15.         public Demo(String s)
  16.         {
  17.                //方案二,明确调用父类的带参构造                      super(s);    而不是super(String s);
  18.                
  19.                 i=2;         
  20.         }
  21.         public static void main(String[] args)
  22.         {
  23.                 Demo d=new Demo("yes");
  24.                 System.out.println(d.i);
  25.         }
  26. }
复制代码
首先我们要了解一下子类加载的过程:

1首先加载父类 ,也就是调用父类的构造方法.

2加载自己的构造方法

     为什么要先调用父类构造呢?因为子类要用到父类中的属性和方法,如果父类构造方法不能调用就证明父类无法初化
就用不了,父类的方法和变量就没法继承.
        创建一个对象必须用到构造方法, 如果父类中没有默认构造方法,系统将会自动给一个无参构造方法并调用
而假如有,包括有有参构造,就不再默认生成,,这时,就要子类明确调用有参构造(方案2), 或者在父类中写一个无参
构造方法.Super(){}  花括号中可以有内容,也可以为空(方案1)

            在此例中,yes没有参与赋值运算,这里的代码不全,Demo d=new Demo("yes");仅仅表示用子类的有参构造方法创建一个子类对象










回复 使用道具 举报
这个问题我在看书的时候也纠结了好久,经过查阅资料和反复验证,给出我的理解
1.子类实例化时先调用父类的构造函数再调用自己的构造函数;
2.默认调用父类的无参构造函数
   a)父类只声明有参构造函数,此时默认构造函数失效,故会报错;
  b)父类没有声明构造函数或声明了无参和有参两种,可以正常运行;
c)父类只声明了有参函数,子类构造函数里显式调用父类的有参构造函数super(参数);
3)此处在父类里显式声明,无参构造函数或者子类调用super(s);
class Super
{
        int i=0;
               
                //public Super(){};   //1.声明无参构造函数
               
        public Super(String S)
        {
                i=1;
        }
}
class Demo extends Super
{
        public Demo(String s)
        {
                                //super(s);     //2.子类调用父类的有参构造函数
                                i=2;
        }
        public static void main(String[] args)
        {
                Super d=new Demo("yes");
                System.out.println(d.i);
        }
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马