用Java中的构造函数inheritance

你能告诉我下面代码中的问题吗?

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不能应用于给定类型;必需:int,int,int; found:无参数;实际和forms参数列表的长度不同。”

但是当我编译它包括被注释的代码(即boxinfo()构造函数)时,它被编译。 为什么需要包含默认构造函数?

通过设置boxinfo(int a, int b, int c)构造函数,可以删除java为boxinfo设置的默认无参数构造函数。 然后,当你调用boxweight(int a,int b,int c,int w)构造函数时,由于boxweight类inheritance自boxinfo ,你隐式调用刚刚被覆盖的boxinfo的默认构造函数。

要避免这种情况,要么在boxinfo创建一个无参数构造函数,要么在boxinfo显式调用super(a, b, c)

由于这是构建实例的超类部分以使某些工作有效所必需的,因此需要调用超级构造函数。

如果在构造函数的第一个语句中没有调用super()的语句(或者以this()结束的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类添加构造函数,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()必须是子类构造函数中的第一行。

当你重载默认构造函数时,这是必要的,默认构造函数不再存在。

例如:

 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

当您使用inheritance扩展类并创建子类的对象时,子类的构造函数将调用其父类构造函数。在您使用下面的构造函数的情况下,它将调用默认构造函数。在您的类中,您没有指定默认构造函数。你可以使用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; }