Java继承-构造函数

Java继承-构造函数,java,inheritance,constructor,Java,Inheritance,Constructor,在准备期末考试时,我在我正在学习的那本书中看到了以下陈述。考虑到以下准则: class A { public A(int x) { } } class B extends A { public B(int x ) { } } 在类B的构造函数中调用类A的构造函数(super(x))是强制性的吗。这本书说这不是强制性的,因为它们有确切的参数数量和类型。但当我在java编译器中尝试此操作时,会抛出以下错误: 类A中的构造函数A不能为空 适用于给定类型;必修的: 找不到in

在准备期末考试时,我在我正在学习的那本书中看到了以下陈述。考虑到以下准则:

class A {
    public A(int x) {   }
}

class B extends A {
    public B(int x ) {   }
}
在类B的构造函数中调用类A的构造函数(super(x))是强制性的吗。这本书说这不是强制性的,因为它们有确切的参数数量和类型。但当我在java编译器中尝试此操作时,会抛出以下错误:

类A中的构造函数A不能为空 适用于给定类型;必修的: 找不到int:没有参数原因: 实际参数和形式参数列表 长短不一


编译器会自动在开头插入
super()

但是,即使是构造函数参数,
super()
(不带参数)也会被添加,从而调用超类的默认构造函数。而你没有一个,因此是错误的

您必须指定
super(x)
(调用
A(x)
),或定义无参数构造函数

顺便说一下,Eclipse编译器提供了一种更好的错误消息:

隐式超级构造函数A()未定义。必须显式调用另一个构造函数


当您没有默认构造函数并且正在使用默认构造函数创建实例时,就会发生这种情况。因为如果您有任何参数化构造函数,那么编译器将不会为您插入默认构造函数,而是您必须进行定义。

编译器似乎试图使用
super()
创建对超类默认构造函数的调用,这是不可用的:

required: int
found:    no arguments
但是回到你的书:我从来没有听说过一条规则,如果实际构造函数与直接超类中的构造函数具有完全相同的参数列表,那么可以跳过构造函数中的
super
语句。仅隐式添加对超类的默认构造函数的调用(
super()
),但这要求超类具有默认构造函数

与你书中所写的内容(或与你对书面文本的理解相反),以下是语言规范中的一句话:

如果构造函数主体不是以显式构造函数调用开头 并且所声明的构造函数不是原始类对象的一部分,那么 编译器隐式地假定构造函数体以超级 类构造函数调用“super();”,对其 不带参数的直接超类


如果基类有一个默认构造函数(没有参数构造函数),那么在扩展
B
时,不需要显式调用
super()
,因为它是以任何方式调用的

但是,当您有一个带参数的构造函数时,当在
B
中创建带参数的构造函数时,您需要为
a
传入
super()

例如:

A类{
公共A(int x){}
}
B类扩展了A类{
公共B(int x)
{
super(x);//需要为类A指定参数
//... 
}
}

对于Java,有必要调用超类的构造函数。因此,每当您生成子类的构造函数时,超类的构造函数都是由IDE自行创建的


这是因为每当基类构造函数需要参数时,编译器都认为这些参数将由基类构造函数填充。如果是默认构造函数,则可以。不需要在子类中调用super()。

在这一行抛出错误:“public B(int x){}”。我在问题中发布的代码就是我试图编译的所有代码(只是类定义,根本没有实例化)。它只会插入
super()
。它不会插入
super(int)
。因此这里出现了错误。在这种情况下,他确实需要调用
super(x)
。看见