黑马程序员技术交流社区

标题: 关于子类实例化的问题 [打印本页]

作者: 唐巍    时间: 2012-3-12 01:38
标题: 关于子类实例化的问题
问题代码:
class Super
{
        int i=0;
        public Super(String s)
        {
                i=1;
        }
}
class Demo extends Super
{
        public Demo(String s)
        {
                i=2;
        }
}
class Test
{
        public static void main(String[] args)
        {
                Demo d=new Demo("yes");//编译失败。提示找不到构造函数,为什么?
                System.out.println(d.i);
        }
}
作者: 蒙武辉    时间: 2012-3-12 01:56
原因很简单,你没有给类Demo初始化。应该调用父类的构造函数给子类初始化‘
class Super
{
        int i=0;
        public Super(String s)
        {
                i=1;
        }
}
class Demo extends Super
{
        public Demo(String s)
        {
                super(s);
                i=2;
        }
}
class Test
{
        public static void main(String[] args)
        {
                Demo d=new Demo("yes");
                System.out.println(d.i);
        }
}
作者: 刘蕴学    时间: 2012-3-12 02:01
本帖最后由 了无尘 于 2012-3-12 02:32 编辑

Implicit super constructor Super() is undefined. Must explicitly invoke another constructor

这个错误今天已经几个人出了,这个意思就是你的父类必须有无参构造函数
  1. class Super
  2. {
  3.         int i=0;
  4.         public Super()
  5.         {
  6.                
  7.         }
  8.         public Super(String s)
  9.         {
  10.                 i=1;
  11.         }
  12. }
  13. class Demo extends Super
  14. {
  15.         public Demo(String s)
  16.         {
  17.                
  18.                 super();
  19.                 i=2;      
  20.         }
  21. }
  22. class Test
  23. {
  24.         public static void main(String[] args)
  25.         {
  26.                 Demo d=new Demo("yes");//编译失败。提示找不到构造函数,为什么?
  27.                 System.out.println(d.i);
  28.         }
  29. }
复制代码
关键点就在于子类里的这个super()上,我们做个测试,
  1. class Super
  2. {
  3.         int i;
  4.         public Super()
  5.         {
  6.                 i=100;
  7.         }
  8.         public Super(String s)
  9.         {
  10.                 i=1;
  11.         }
  12. }
  13. public class Demo extends Super
  14. {
  15.         public Demo(String s)
  16.         {
  17.                
  18.                 super();
  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. }
复制代码
这里的子类构造函数中的super()调用了父类的无参构造函数,所以结果为102,但我们把这个super()注释了,结果还是102,因为默认的会调用父类的无参构造函数,所以我们必须手动指定一个无参的构造函数

在看下边这个代码
  1. class Super
  2. {
  3.         int i;

  4.         public Super(String s)
  5.         {
  6.                 i=1;
  7.         }
  8. }
  9. public class Demo extends Super
  10. {
  11.         public Demo(String s)
  12.         {
  13.                
  14.                 super(s);
  15.                 i+=2;      
  16.         }
  17.         public static void main(String[] args)
  18.         {
  19.                 Demo d=new Demo("super");//编译失败。提示找不到构造函数,为什么?
  20.                 System.out.println(d.i);
  21.         }
  22. }
复制代码
结果为3,而且父类没有无参构造函数,原因是子类的有参构造第一句的super(s)覆盖了默认的super(),在父类里这个有参的构造函数是存在的,所以并不会发生问题

构造函数的补全功能是 类里并没有构造函数的情况下,为你补全一个空的构造函数,所以在你有有参构造函数的情况下是不会自动补全的。
作者: 王睿    时间: 2012-3-12 02:23
子类的每个构造函数第一行都默认有super();  就是默认会调用父类的空参数构造函数,所以父类要有空参数的构造函数。

或者手动指定,super(“s”);去调用父类有参的构造。
作者: 贠(yun)靖    时间: 2012-3-12 02:51
子父类中的构造函数
      在对子类对象初始化时,父类的构造函数也会运行,因为子类的所有构造函数的默认第一行都有一条隐士的语句为super()——会访问父类中空参数的构造函数,并且它一定定义在子类的构造函数的第一行。       
   为什么子类一定要访问父类中的构造函数。
                因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类时如何对这些数据进行初始化的。所以子类在对对象初始化时,要先访问以下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。               
   所以 你要么在你的Demo构造函数中第一行写 super()  要么就在Super父类里面添加一个空参数的构造函数  即 Super(){}
作者: 袁野    时间: 2012-3-12 06:40
子类在继承父类的时候
子类的构造函数会加载父类的构造函数 当父类的构造函数是默认的 子类可以不使用super()语句
class Demo extends Super
{
        public Demo(String s)
        {
super(s);-------------------------------少了这句话
                i=2;
        }
}
作者: 张希强    时间: 2012-3-12 09:22
以后如果自定义类新的构造方法时别忘记写上类默认的不带参数的构造函数,这样可以避免很多错误。
作者: 泮和顺    时间: 2012-3-12 09:50
本帖最后由 泮和顺 于 2012-3-12 09:51 编辑

其实简单点说就是构造函数无法被复写的,不具备被复写的条件的,类名不可能一样不可能复写或是重载都没意义的,可以在类中加上super(s) 等效于调用父类构造函数的里面的定义格式
作者: baypm_jy    时间: 2012-3-12 11:12
package com.iwit.test;

class Super {
        int i = 0;

       
        public Super(String s) {
                i = 1;
        }
}

class Demoa extends Super {
        public Demoa(String s) {
                super(s);
                i = 2;
        }
}

class Tests {
        public static void main(String[] args) {
                Demoa d = new Demoa("yes");// 编译失败。提示找不到构造函数,为什么?
                System.out.println(d.i);
        }
}




package com.iwit.test;

class Super {
        int i = 0;

        public Super(){
        }
        public Super(String s) {
                i = 1;
        }
}

class Demoa extends Super {
        public Demoa(String s) {
                i = 2;
        }
}

class Tests {
        public static void main(String[] args) {
                Demoa d = new Demoa("yes");// 编译失败。提示找不到构造函数,为什么?
                System.out.println(d.i);
        }
}






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2