父 class 是否总是需要默认或无参数构造函数,即使子 class 已经定义了构造函数?

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;
    }
}

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

我得出父 class 总是需要默认或无参数构造函数的结论是否正确?如果我希望父子 class 只有带参数的构造函数怎么办?

Am I right to conclude that a parent class always needs a default or no-arg constructor?

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

您的代码应该是:

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

看,超类已经有年龄字段,可能还有使用该字段的方法。所以在子类中重新声明一个是错误的并且适得其反。

要使其编译为您需要调用 super(int) 而不是隐式调用 super()

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

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

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

这是继承的美妙之处:您可以使用任何已经写在基础中的东西 class。


However, the compiler complains that the parent class has no default constructor.

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

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.

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


What if I want the parent and child class to only have constructors with parameters?

那么子 class 应该总是明确说明它想调用父的构造函数。


Am I right to conclude that a parent class always needs a default or no-arg constructor?

不,只要其子项不调用 super().

,父项 class 就可以没有默认构造函数