我正在做一个简单的继承程序,但是在做这个程序时我感到很困惑。
这是一个简单的程序:
class Box {
double width;
double height;
double depth;
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
//Error on removing the Box() Constructor
Box() {
width = -1;
height = -1;
depth = -1;
}
double volume() {
return width * height * depth;
}
}
class BoxWeight extends Box {
double weight,h,w,d;
BoxWeight(double w, double h, double d, double m) {
// If i add super(w,h,d) here, then it is working, WHy?
this.h = h;
this.d = d;
this.w = w;
weight = m;
}
}
class DemoBoxWeight {
public static void main(String args[]) {
//Implementation of above
}
}
令我感到困惑的是,当我删除Box()
构造函数时,它会在线上给出错误,其中BoxWeight(double w, double h, double d, double m)
构造函数已定义。 The error is: "constructor Box in class Box cannot be applied to given types".
如果我从super()
内拨打BoxWeight()
,那么它可以正常工作。我不明白为什么?我知道这个概念非常简单,但我很难理解它。感谢任何帮助。
答案 0 :(得分:4)
您的构造函数Box()
未显式调用超级构造函数。这意味着将调用默认构造函数BoxWeight
。
如果删除该构造函数或使其无法从BoxWeight(double w, double h, double d, double m) {
super(w,h,d);
this.h = h;
this.d = d;
this.w = w;
weight = m;
}
访问,则会出现此错误。
你可以做的是明确地调用另一个构造函数,正如你已经发现的那样:
{{1}}
继承的类只能通过调用超类的构造函数来构造。
答案 1 :(得分:2)
当您创建子类的对象时,如果您没有显式调用该类的直接超类的构造函数,则隐式地调用该直接超类的默认构造函数(并且这个链继续继承继承层次结构)。
这是您对super(w, h, d)
的调用所做的事情。您正在显式调用Box的超类构造函数。在这种情况下,省略了对super()
的隐式调用。 super()
是对超类的默认构造函数的调用。但由于您没有包含默认构造函数,因此会导致错误。
但是,假设您为Box类添加了一个默认构造函数。那么这段代码应该可以正常工作,因为现在,对super()
的调用会调用超类的默认构造函数
答案 2 :(得分:2)
当一个类没有定义自己的构造函数时,语言会自动提供一个默认的隐式无参数构造函数。
当一个类定义至少一个构造函数时,该语言不提供隐式构造函数,因此该类只能使用它定义的构造函数之一进行实例化。
当派生类的构造函数不调用其超类的任何构造函数时,该语言会自动提供对super()
的隐式调用。但为了使其工作,超类必须具有(显式或隐式)无参数构造函数。
因此,上面代码发生的事情是BoxWeight
的构造函数没有显式调用super()
,因此语言提供了对super()
的隐式调用。这是有效的,因为Box
定义了一个显式的无参数构造函数Box()
。
当您删除显式无参数构造函数Box()
时,编译器没有Box
的构造函数从BoxWeight
构造函数中调用。它不能调用剩余的构造函数,因为它接受参数,编译器不能只决定要传递的参数。正如您自己发现的那样,如果您调用接受参数的Box
构造函数,则代码会再次编译。
此外,请注意以备将来参考:“它给我一个错误”并不是对问题的充分描述。它会为您提供一个非常具体的错误,您必须在问题中包含该错误。错误是:“类Box中的构造函数Box不能应用于给定类型”。
答案 3 :(得分:1)
当您删除默认构造函数Box
时,程序中实际发生的情况是编译器没有从BoxWeight
构造函数中调用的构造函数。这会给编译器带来困惑,因此它会给你一个
错误。
但是,当您提供对接受参数的Box
构造函数的调用时,您的代码会编译而不会出现任何错误。