为什么默认构造函数在父类中是必需的(显式),如果它有一个有争议的构造函数
class A {
A(int i){
}
}
class B extends A {
}
class Main {
public static void main(String a[]){
B b_obj = new B();
}
}
Run Code Online (Sandbox Code Playgroud)
这将是一个错误.
Jon*_*eet 71
这里有两个方面:
如果确实明确指定了构造函数(如A),Java编译器将不会为您创建无参数构造函数.
如果没有显式指定构造函数(如B),Java编译器将为您创建一个无参数构造函数:
B()
{
super();
}
Run Code Online (Sandbox Code Playgroud)(可访问性取决于类本身的可访问性.)
那是试图调用超类无参数构造函数 - 所以它必须存在.您有两种选择:
AB其中显式调用具有适当int参数的基类构造函数.Swa*_*ika 11
为什么默认构造函数在父类中是必需的(显式),如果它有一个有争议的构造函数
我会说这句话并不总是正确的.理想情况下,它不是必需的.
规则是:如果您明确提供了参数化的构造函数,则该类无法使用默认构造函数(非参数化).
For Example :
class A {
A(int i){
}
}
class B extends A {
}
Run Code Online (Sandbox Code Playgroud)
所以当你写作
B obj_b = new B();
Run Code Online (Sandbox Code Playgroud)
它实际上将java提供的隐式构造函数调用到B,它再次调用super(),理想情况下应该是A().但是既然你已经为A提供了参数化的构造函数,那么默认构造函数i:e A()不可用于B().
这就是你需要为B()专门声明A()来调用super()的原因.
小智 8
如果子类构造函数没有显式调用超类的其他构造函数,则每个子类构造函数都会调用超类的默认构造函数.因此,如果您的子类构造函数显式调用您提供的超类构造函数(带参数),那么超类中不需要任何参数构造函数.那么,以下将编译:
class B extends A{
B(int m){
super(m);
}
}
Run Code Online (Sandbox Code Playgroud)
但是除非你在超类中明确地没有提供args构造函数,否则以下内容将无法编译:
class B extends A{
int i;
B(int m){
i=m;
}
}
Run Code Online (Sandbox Code Playgroud)
假设你打算写class B extends A:
每个构造函数都必须调用一个超类构造函数; 如果不是,则隐式调用无参数超类构造函数.
如果(且仅当)一个类声明没有构造函数,Java编译器为它提供一个默认构造函数,它不接受任何参数并调用超类的无参数构造函数.在您的示例中,A声明一个构造函数,因此没有这样的默认构造函数.类B不声明构造函数,但不能获取默认构造函数,因为它的超类没有要调用的无参数构造函数.由于类必须始终具有构造函数,因此这是编译器错误.
Why default constructor is required(explicitly) in a parent class if it
has an argumented constructor
Run Code Online (Sandbox Code Playgroud)
不必要!
现在在你的 B 班
class B extends A {
}
Run Code Online (Sandbox Code Playgroud)
您尚未在 B 类中提供任何构造函数,因此将放置默认构造函数。现在的规则是每个构造函数都必须调用它的超类构造函数之一。在您的情况下,B 类中的默认构造函数将尝试调用 A 类(它的父类)中的默认构造函数,但由于您在 A 类中没有默认构造函数(因为您在 A 类中明确提供了带有参数的构造函数,因此您将在 A 类中没有默认构造函数)你会得到一个错误。
你可能会做的是
在 A 类中不提供 args 构造函数。
A()
{
//no arg default constructor in Class A
}
Run Code Online (Sandbox Code Playgroud)
或者
明确地在 B 中写入 no args 构造函数,并使用一些默认的 int 参数调用您的 super。
B()
{
super(defaultIntValue);
}
Run Code Online (Sandbox Code Playgroud)
底线是,要创建一个对象,必须调用继承层次结构中每个父级的完全构造函数。调用哪个实际上是您的设计选择。但是,如果您没有明确提供任何 java 会将默认构造函数 super() 调用作为每个子类构造函数的第一行,现在如果您在超类中没有它,那么您将收到错误。