Java中带构造函数的继承

Java中带构造函数的继承,java,inheritance,constructor,Java,Inheritance,Constructor,你能告诉我下面代码中的问题吗 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() {

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

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;找到:无参数;实际参数列表和形式参数列表长度不同。“


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

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

如果构造函数的第一个语句中没有调用
super()

由于没有不带参数的构造函数,因此无法编译,因为没有与此语句匹配的构造函数

同样,如果一个类没有定义任何构造函数,那么

public MyClass(){ super(); }
如果
MyClass
的超类只提供一个构造函数,其参数如

如果隐式声明了默认构造函数,但超类没有可访问的构造函数(§6.6),且该构造函数不带参数且没有throws子句,则这是编译时错误


要纠正您的问题,只需调用正确的超级构造函数或定义一个没有参数的构造函数(不再称为默认构造函数,只有编译器定义的构造函数是默认构造函数;)

通过设置
boxinfo(int a,int b,int c)
构造函数,java为
boxinfo
设置的默认无参数构造函数将被删除。然后,当您调用
boxweight(inta,intb,intc,intw)
构造函数时,由于
boxweight
类继承自
boxinfo
,因此您隐式调用了刚刚被覆盖的
boxinfo
中的默认构造函数


为了避免这种情况,您可以在
boxinfo
中创建一个无参数构造函数,或者在
boxweight
中显式调用
super(a,b,c)
,当您重载默认构造函数时,有必要这样做,默认构造函数不再存在

例如:

实际上与:

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工件


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

子类构造函数调用父类的构造函数 需要四个参数

boxinfo
类中没有需要四个参数的构造函数 参数

此外,

Java编译器会自动将
super()
构造函数插入子类。
这个超级构造函数的意思是在父类中执行一个不带参数的构造函数

根据您的计划:

boxinfo(int a, int b, int c) {
        l = a;
        this.b = b;
        h = c;
    }
运行程序编译器时,请删除默认构造函数,因为父类中的构造函数接受三个参数

如果没有为
boxweight
类添加构造函数,Java编译器会自动插入默认构造函数。由于您添加了四个参数,编译器将检查四参数构造函数。正如我之前所说,当您在构造函数中扩展另一个类(
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
这个.b=b,和
h=c
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;
    }

注意:添加
super()
时必须是子类构造函数的第一行。

为什么不调用super?因为boxweight继承自boxinfo,所以需要在侧注上使用super(参数)从boxweight调用boxinfo的构造函数,Java中的类应该以大写字母开头,可能是某个人在没有明显原因的情况下否决了它的副本。这是一个很好的答案。@f1sh它未能解决问题中的实际问题,即对
super()
的隐式调用是无效的added@Matsemann它就在答案的前两句中。@f1sh不,这是编辑后的另一个问题:为什么要重新分配
l
b
h