错误记录--Java中子类继承父类必须调用父类的构造方法?

当子类继承父类并删除构造方法中的super调用时,编译器报错,提示必须显示调用另一个构造方法。原因在于,如果父类的所有构造方法都有参数,它将失去默认构造方法,需手动添加。子类创建时会尝试调用父类无参构造,若不存在则报错。使用super关键字显式调用父类构造方法,必须作为子类构造方法的第一条语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚睡完午觉起来,有点迷糊,然后接着练习Java中元组(tuple)的时候突然就遇到这么个问题,关于继承的问题,奇怪在睡觉之前怎么就没发现这个问题呢,传说中的“面向睡一觉编程”吗。。。Orz

先贴上代码:
首先是创建一个父类文件TwoTuple.java

package test.fifth;

public class TwoTuple<A, B> {
    public A first;
    public B second;

    public TwoTuple(A a, B b) {
        first = a;
        second = b;
    }

    public String toString() {
        return "( " + first + "," + second + " )";
    }
}

接下来是子类文件ThreeTuple.java

package test.fifth;

public class ThreeTuple<A, B, C> extends TwoTuple<A, B> {
    public C third;

    public ThreeTuple(A a, B b, C c) {
        super(a, b);
        third = c;
    }

    public String toString() {
        return "(" + first + "," + second + "," + third + ")";
    }
}

当然,现在这两个类都没有问题。

但是当我将ThreeTuple类的构造方法中的super(a,b)删除后,就会报一个错误,如下:

Implicit super constructor TwoTuple< A,B >() is undefined. Must explicitly invoke another constructor

翻译下:隐式的父类构造方法TwoTuple< A,B >是未定义的,必须显示的调用另一个构造方法。


下面整理下错误:当我使用子类ThreeTuple时,在其构造方法中没有调用父类的构造方法,这时候编译器报错,难道子类继承父类时,必须调用父类的构造方法吗?

然后,试着找找解决办法,根据报错,自然想到在父类(TwoTople)中寻找线索,果然,
在我删除子类构造方法中的super(a,b)后,再到父类中,增加个默认构造方法之后,错误就消失了,如下:
TwoTuple.java

    public TwoTuple() {
    }

什么?默认构造方法不是应该编译器自动添加的吗?这里怎么会需要手动添加呢?不科学啊啊啊。。。难道是还没睡醒?赶紧给自己两耳光清醒清醒。。。

好吧,清醒过来还得继续找出原因


下面是经过一番搜索找到的解答整理:

默认构造方法的概念:
默认构造方法是没有参数的构造方法,可以简单的分为两种:
(1) 隐式的默认构造方法
(2) 显式定义的构造方法
在java语言中,每个类至少有一个构造方法,为了保证这一点,如果用户定义的类中没有构造方法,那么java语言将自动提供一个隐含的默认构造方法,该构造方法没有参数,用public修饰,没有返回值,并且方法体为空,例如:

    public TwoTuple(){
    }

当然在程序中也可以明确的定义默认构造方法,
如果在类中定义了一个或者多个构造方法,并且所有的构造方法都有参数,这个类就失去了默认的构造方法(!!!整个问题的关键就在这里!!!)。如果想保留默认的构造方法,必须显式的定义出来。例如:

public class TwoTuple<A, B> {
    public A first;
    public B second;

    public TwoTuple(A a) {
        System.out.println(a);
    }

    public TwoTuple(A a, B b) {
        System.out.println(a + "," + b);
    };

}

对于这个类,如果要定义一个对象 TwoTuple test = new TwoTuple() 这个就是错误的,因为这样定义是通过默认无参构造方法进行初始化,但是在这个类中没有这个构造方法,如果想这样定义,必须显式的定义默认无参构造方法



子类调用父类的构造方法:

父类的构造方法不能被子类继承这里回答了标题的问题),但是在子类对象被创建时,如果不显式调用父类的构造方法,这时子类会调用父类的无参构造方法,如果父类没有无参构造方法(也就是如上面所述),则Java编译器将报告错误。如果要调用父类的其他构造方法(带参构造方法),必须出使用super显式的指
使用super必须遵循以下规则:
(1) 在子类的构造方法中不能直接使用父类的构造方法名称直接调用,而必须使用super语句
(2) 如果在子类的构造方法中时用super调用父类的构造方法,他必须作为构造方法的第一条语句出现。

总结:在创建子类的对象时,java虚拟机首先执行父类的构造方法,然后再执行子类的构造方法,在多重继承的情况下,将从最顶层的类的构造方法开始执行,然后依次执行各个类的构造方法



以上,一觉醒来还学到不少东西,哈哈,以后要多睡觉!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值