如果父类具有参数构造函数,为什么在父类中需要默认构造函数?

bha*_*ran 48 java

为什么默认构造函数在父类中是必需的(显式),如果它有一个有争议的构造函数

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)

(可访问性取决于类本身的可访问性.)

那是试图调用超类无参数构造函数 - 所以它必须存在.您有两种选择:

  • 显式提供无参数构造函数 A
  • 提供一个无参数构造函数,B其中显式调用具有适当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)


Mic*_*rdt 7

假设你打算写class B extends A:

每个构造函数都必须调用一个超类构造函数; 如果不是,则隐式调用无参数超类构造函数.

如果(且仅当)一个类声明没有构造函数,Java编译器为它提供一个默认构造函数,它不接受任何参数并调用超类的无参数构造函数.在您的示例中,A声明一个构造函数,因此没有这样的默认构造函数.类B不声明构造函数,但不能获取默认构造函数,因为它的超类没有要调用的无参数构造函数.由于类必须始终具有构造函数,因此这是编译器错误.


Ani*_*kur 6

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() 调用作为每个子类构造函数的第一行,现在如果您在超类中没有它,那么您将收到错误。