[英]Inheritance with constructor in Java
您能在下面的代码中告诉我这个问题吗?
class boxdemo1 {
public static void main(String args[]) {
boxweight weightbox = new boxweight(2, 3, 5, 4);
System.out.println(weightbox.volume());
}
}
class boxinfo {
int l, b, h;
/*
* boxinfo() { l=b=h=-1; }
*/
boxinfo(int a, int b, int c) {
l = a;
this.b = b;
h = c;
}
int volume() {
return l * b * h;
}
}
class boxweight extends boxinfo {
int w;
boxweight(int a, int b, int c, int w) {
l = a;
this.b = b;
h = c;
this.w = w;
}
}
当我对其进行编译时,它显示以下错误:“类boxinfo中的构造方法boxinfo无法应用于给定类型; required:int,int,int; found:无参数;实际和形式参数列表的长度不同。”
但是,当我编译包含注释的代码(即boxinfo()构造函数)时,它将被编译。 为什么必须包含默认构造函数?
由于这是构建实例的超类部分以使其正常工作所必需的,因此必须调用超级构造函数。
如果在构造函数的第一条语句中没有调用super()
的语句(或以super()
结尾的this()
super()
),则编译器会将调用添加到默认构造函数 ( super();
)。
由于您没有没有参数的构造函数,因此无法编译,因为没有与该语句匹配的构造函数。
同样,如果一个类没有定义任何构造函数,则会实现一个默认的构造函数,例如
public MyClass(){ super(); }
如果MyClass
的超类仅向构造函数提供如JLS中所述的参数,则会出现相同的问题
如果隐式声明了默认构造函数,但超类没有可访问的构造函数(第6.6节),该构造函数不带参数且不包含throws子句,则这是编译时错误。
要解决您的问题,只需调用正确的超级构造函数或定义不带参数的构造函数(不再称为默认构造函数,只有编译器定义的是默认的;))。
错误原因-
子类的构造函数调用具有四个参数的父类的构造函数。
boxinfo
类中没有使用四个参数的构造函数。
此外,
Java编译器会自动将super()
构造函数插入子类。 这个超级构造器的意思是Go并在父类中执行一个不带参数的构造器 。
根据您的程序:
boxinfo(int a, int b, int c) {
l = a;
this.b = b;
h = c;
}
在运行程序编译器时,请删除默认构造函数,因为父类中的构造函数带有三个参数。
如果不为boxweight
类添加构造函数, boxweight
Java编译器会自动插入默认构造函数。 由于已经添加了四个参数,因此编译器将检查四个参数的构造函数。 就像我之前说过的,当您在构造函数中extends
另一个类( boxinfo
)时,Java编译器也会自动将super()
插入构造函数的第一行。
看起来像这样:
class boxweight extends boxinfo{
boxweight (int a, int b, int c, int w){
super();
//.....
}
}
我们可以将super()
添加到子类的构造函数中,使其与父类中的现有构造函数匹配。
解决您的问题,
在子类的构造函数(第一行)中添加super()
并添加值以匹配父类的构造函数。
像这样:
boxweight(int a, int b, int c, int w) {
super(a, b, c);
this.w = w;
}
现在您不需要这些分配l = a;
, this.b = b;
,且h = c;
因为您可以通过构造函数将其发送给父类。
注意:添加super()
必须是子类构造函数中的第一行。
通过设置boxinfo(int a, int b, int c)
构造函数,将删除java为boxinfo
设置的默认无参数构造函数。 然后,当您调用boxweight(int a,int b,int c,int w)
构造函数时,由于boxweight
类继承自boxinfo
,因此您将隐式地从boxinfo
调用默认的构造函数,而该默认构造boxinfo
已被覆盖。
为了避免这种情况,无论是在自己创建的无参数的构造函数boxinfo
或显式调用super(a, b, c)
中boxweight
当您重载默认构造函数时,这是必要的,默认构造函数不再存在。
例如:
class boxweight extends boxinfo {
boxweight(int a, int b, int c, int w) {
...
}
}
实际上与:
class boxweight extends boxinfo {
boxweight(int a, int b, int c, int w) {
super();
...
}
}
但是在boxinfo
这样的构造函数已不存在,您可以创建自定义构造函数。 您需要将其保留在代码中以使其可调用。
子类构造函数必须通过调用其超类的构造函数中的至少一个来初始化其超类成员。
如果超类没有默认的构造函数(如您的示例中的构造函数),则这是强制性的。
在这种情况下, boxweight
构造函数必须初始化boxinfo
声明的其他成员。 因此,您必须调用super(...)
来初始化boxinfo
。
因此,您的boxweight
构造函数将变为:
boxweight(int a, int b, int c, int w) {
super(a,b,c); // put this call here and remove other lines.
this.w = w; // this is sufficient
}
PS:我建议您遵循命名约定来命名类,方法和其他Java工件。
http://www.oracle.com/technetwork/java/codeconventions-135099.html
当您使用继承扩展类并创建子类的对象时,子类的构造函数将调用其父类构造函数。在您使用的情况下,您将在下面的构造函数中调用默认构造函数。在这种情况下,您可以使用super调用父类中声明的构造函数。
boxweight(int a, int b, int c, int w) {
super(a, b, c); //or declared default constructor
l = a;
this.b = b;
h = c;
this.w = w;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.