黑马程序员技术交流社区

标题: 关于继承中的构造方法的问题 [打印本页]

作者: 黄小钒    时间: 2012-3-28 13:11
标题: 关于继承中的构造方法的问题
class SuperClass
{
        private int n;
        /*   
        SuperClass()      
        {
                System.out.println("SuperClass()");
        }*/
        SuperClass(int n)
        {
                System.out.println("SupserClass("+n+")");
                this.n=n;
        }

}

class SubClass extends SuperClass
{
        private int n;
        SubClass(int n)
        {
                System.out.println("SubClass("+n+")");
                this.n = n;
        }
        SubClass()
        {
                super(300);   // 此处调用了父类有参数的构造方法,为何为提示找不到无参构造函数 SuperClass()呢?
                System.out.println("SubClass");
        }
}
public class TestSuperSub
{
        public static void main(String[] args)
        {
                SubClass sc1= new SubClass();   //  编译出错  提示找不到构造函数SuperClass();
                //SubClass sc2= new SubClass(400);
        }
}
作者: 杨华威    时间: 2012-3-28 13:35
        /*   
        SuperClass()      
        {
                System.out.println("SuperClass()");
        }*/
因为你把父类的SuperClass构造方法给注释掉了。请打开它。就ok了!

作者: 黄小钒    时间: 2012-3-28 13:39
我是把它注释了,可是 我调用的是有参数的构造方法,跟无参数的构造方法 有关系吗?
作者: 李征雪    时间: 2012-3-28 13:40
你的这个SubClass sc1= new SubClass();  
是没有参数的,你调用的无参数构造函数被注释掉了。
作者: 黄小钒    时间: 2012-3-28 13:40
杨华威 发表于 2012-3-28 13:35
/*   
        SuperClass()      
        {

我是把它注释了,可是 我调用的是有参数的构造方法,跟无参数的构造方法 有什么关系呢?
作者: izwj    时间: 2012-3-28 13:47
如果你不写构造函数,系统会给你自动加上默认构造函数,如果你写了构造函数,默认的空参数构造函数就没有了,如果使用就必须写出来。
作者: adison    时间: 2012-3-28 13:49
黄小钒 发表于 2012-3-28 13:40
我是把它注释了,可是 我调用的是有参数的构造方法,跟无参数的构造方法 有什么关系呢?  ...

如果你注释  /*   
        SuperClass()      
        {
                System.out.println("SuperClass()");
        }*/
没去掉的话,SubClass(int n)
        {     
                super(XX);//必须要有,因为默认会调用super();而父类中已经没空参数构造函数
                System.out.println("SubClass("+n+")");
                this.n = n;
        }
作者: 杨华威    时间: 2012-3-28 13:50
每个子类构造方法中的第一行,系统默认添加一句super();去父类中初始化。当你自己写了初始化方法后,默认就会消失。
例子中,你把父类的不带参数的构造方法注释掉了,子类SubClass(int n)中的系统默认添加的super();去父类中进行初始化,找不到无参数的构造方法,那么,肯定会编译失败。
方法是:
1,打开父类注释掉的无参数构造方法。
2,不去掉注释的话,你可以在SubClass(int n)构造方法中的第一行添加上一句super(n);让它去父类SuperClass(int n)中进行初始化。也是允许的。

鉴定完毕。
作者: 杨华威    时间: 2012-3-28 13:59
黄小钒 发表于 2012-3-28 13:40
我是把它注释了,可是 我调用的是有参数的构造方法,跟无参数的构造方法 有什么关系呢?  ...

SubClass(int n)构造方法中代码的第一行如果你不进行初始化,系统会默认添加super();去调用父类的方法进行初始化。显然,父类的无参数构造方法被你注释掉了,那么久找不到指定的构造器了。
我在8楼已经说明白了。
作者: 抓哇    时间: 2012-3-28 14:04
这个东西是有点拗人的

作为父类当且仅当你没有任何构造函数时候系统才会给你默认生成个无参数构造函数 而你现在是有个带参的构造函数了他就不给你生成了的

     SubClass(int n)
        {       //这里隐士调用super()  而却找不到所以就出错
                System.out.println("SubClass("+n+")");
                this.n = n;
        }

解决办法有个2个 第一吧无参构造函数加上

第2个也可以吧子类的无参数构造函数给去掉 也一样的

事实上JAVA体系里很多类都是没无参构造函数 比如动态代理类
           
作者: 许飞翔    时间: 2012-3-28 14:12

class SuperClass
{
        private int n;
         
        SuperClass()      
        {
                System.out.println("SuperClass()");
        }
        SuperClass(int n)
        {
                System.out.println("SupserClass("+n+")");
                this.n=n;
        }

}

class SubClass extends SuperClass
{
        private int n;
        SubClass(int n)
        {
                System.out.println("SubClass("+n+")");
                this.n = n;
        }
        SubClass()
        {
                //Super(100);   // 此处调用了父类有参数的构造方法,为何为提示找不到无参构造函数 SuperClass()呢?
                System.out.println("SubClass");
        }
}
public class TestSuperSub
{
        public static void main(String[] args)
        {
                SubClass sc1= new SubClass();   //  编译出错  提示找不到构造函数SuperClass();
                SubClass sc2= new SubClass(400);
        }
}

super(300);这个你调用的是什么?把这一句去掉就能编译了。
作者: 朱俊    时间: 2012-3-28 14:13
本帖最后由 朱俊 于 2012-5-16 15:03 编辑

~~~~~~~~~~~~~~~~
作者: 和心愿    时间: 2012-3-28 15:20
子类对象在实例化之前必须首先调用父类中的构造方法之后再调用自身的构造方法。系统会默认添加super();去调用父类的方法进行初始化
那段代码被你注释了,找不到因此编译通不过
作者: 葛尧    时间: 2012-3-28 15:56
本帖最后由 葛尧 于 2012-3-28 15:57 编辑
  1. SubClass sc1= new SubClass();   //  编译出错  提示找不到构造函数SuperClass();
复制代码
此句 new SubClass() 创建的对象在无参数构造函数SubClass()中进行了初始化
所以读到了SubClass 类中
  1. SubClass()
  2.         {
  3.                 super(300);   // 此处调用了父类有参数的构造方法,为何为提示找不到无参构造函数 SuperClass()呢?
  4.                 System.out.println("SubClass");
  5.         }
复制代码
显示的调用了父类有参构造函数  思路上是没有错的!


不过以上代码不修改编译是无法通过的。

在子类SubClass  中还有一个有参数构造函数,里面里面默认了一个super();
  1. SubClass(int n)
  2.         {
  3.                 System.out.println("SubClass("+n+")");
  4.                 this.n = n;
  5.         }
复制代码
所以编译时期检测到这里会调用super();  
然而父类里面的无参构造函数被你注释掉了,本来也是隐式存在的。
但是父类中你又定义了有参构造函数。。
结果就是找不到那个无参构造函数(在没任何定义下就是默认构造函数)了
在上句里加入super(参数);就可以通过了,或者就是打开你那个无参数的构造函数

作者: 黄小钒    时间: 2012-3-28 16:49
葛尧 发表于 2012-3-28 15:56
此句 new SubClass() 创建的对象在无参数构造函数SubClass()中进行了初始化
所以读到了SubClass 类中显示的 ...

看了楼上的各位的 差点就看晕了,  到你这里完全看明白了,之前没看到还有一个 SubClass(int n)需要调用无参构造函数,楼上的同学们 多谢了!  谢谢各位的指点!  :D
       
作者: 吴玉辉    时间: 2012-3-28 18:21
我觉得是:SubClass sc1= new SubClass();这一句是你建立了一个在Subclass类中空参数的cs1对象,在对象调用方法时,即指向了Subclass中的空参数构造函数,在空参数构造函数中,你又建立了一个调用父类有参数的构造函数,如果仅仅让编译通过,只需要将super(400)放入到有参数的构造函数中subclass(int n){};建立对象改成SubClass sc1= new SubClass(随便输入一个整数数);有一点明确的是本类构造函数复写父类的方法或者调用父类方法时(super语句),你的参数列表要一致,如果不一致需重新在本类中建立对象,由此对象调用父类中的方法。
作者: 姜志钦    时间: 2012-3-28 20:14
综上,1.如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写super语句,效果都是一样的。2.如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。 3.如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中同上述两规则。 4.若存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类调用,一直到执行顶级父类object类的无参构造方法。
此外:A.在构造方法中如果有this 或 super语句出现,只能是第一条语句。B.在一个构造方法中不允许同时出现this和super语句。C.在类方法中不允许出现this或super关键字。C.在实例方法中this和super不要求第一条语句,可以共存。




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