繁体   English   中英

即使子类已经有一个已定义的构造函数,父类是否总是需要一个默认或无参数的构造函数?

[英]Does a parent class always need a default or no-argument constructor even if the child class already has a defined constructor?

我无法编译这段代码。

class Horse {
    private int age;
    Horse(int age) {
        this.age = age;
    }
}

class Pony extends Horse {
    private int age;
    Pony(int age) { //here compiler complains about no default constructor in parent class
        this.age = age;
    }
}

我知道当父类只有带参数的构造函数时,你必须为子类定义一个构造函数,这就是我所做的。 但是,编译器抱怨父类没有默认构造函数。

我是否正确地得出结论父类总是需要默认或无参数构造函数? 如果我希望父类和子类只包含带参数的构造函数,该怎么办?

我是否正确地得出结论父类总是需要默认或无参数构造函数?

不。子类构造函数必须做的第一件事是调用其中一个超类构造函数。 如果不这样做,那么编译器会为您调用超类的no-arg构造函数。 但是,如果超类没有超级类,那当然会失败。

你的代码应该是:

class Pony extends Horse {
    Pony(int age) {
        super(age);
    }
}

请参阅,超类已经有一个age字段,可能还有使用该字段的方法。 因此,在子类中重新声明一个是错误的并且适得其反。

要使它编译到你需要调用super(int)而不是隐式调用super()

Pony(int age) {
    super(age);
    this.age = age;
}

然后您可能会注意到HorsePony都具有完全相同的字段,其中包含完全相同的数据。 为什么Pony需要有领域age ,如果类Pony是基于( Horse )已定义这个领域?

Pony(int age) {
    super(age);
}

这是继承之美:你可以利用已经在基类中编写的任何东西。


但是,编译器抱怨父类没有默认构造函数。

它抱怨是因为,正如我上面提到的,它无法调用super()

如果构造函数体不以显式构造函数调用开始并且声明的构造函数不是原始类Object的一部分,那么构造函数体隐式地以超类构造函数调用“super();”开头,这是对构造函数的调用。它的直接超类不带参数。

https://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.8.7


如果我希望父类和子类只包含带参数的构造函数,该怎么办?

然后子类应该始终显式地声明它想要调用的父构造函数。


我是否正确地得出结论父类总是需要默认或无参数构造函数?

不,没有默认构造函数的父类是没关系的,只要它的子元素不调用super()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM