我正在做一个简单的继承程序,但在做这个程序时我感到困惑。
这是一个简单的程序:
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".
如果我从BoxWeight()
中调用super()
,那么它工作正常。我不明白为什么??我知道这个概念很简单,但我很难理解。我们非常感谢您的帮助。
您的构造函数BoxWeight(double w, double h, double d, double m)
不会显式调用超级构造函数。这意味着调用了默认构造函数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;
}
继承类只能通过调用超类上的构造函数来构造。
当您创建子类的对象时,如果您没有显式地调用该类的立即超类的构造函数,则会隐式地调用立即超类默认构造函数(并且此链在继承层次结构上继续)。
这就是您对super(w, h, d)
的调用所做的操作。您正在显式地调用Box的超类的构造函数。在这种情况下,省略了对super()
的隐式调用。super()
是对超类的默认构造函数的调用。但由于您没有包含默认构造函数,因此会导致错误。
但是,假设您向Box类添加了一个默认构造函数。然后这个代码也应该可以正常工作,因为现在,对super()
的调用调用了超类的默认构造函数
当一个类没有定义自己的构造函数时,该语言会自动提供默认的隐式无参数构造函数。
当一个类定义了至少一个构造函数时,那么该语言不会提供任何隐式构造函数,因此该类只能使用它定义的构造函数之一进行实例化。
当派生类的构造函数不调用其超类的任何构造函数时,该语言会自动提供对super()
的隐式调用。但要实现这一点,超级类必须有一个(显式或隐式)无参数构造函数。
因此,上面代码发生的情况是BoxWeight
的构造函数没有显式调用super()
,因此该语言提供了对super()
的隐式调用。这是有效的,因为Box
定义了一个显式的无参数构造函数Box()
。
当移除显式无参数构造函数Box()
时,编译器在BoxWeight
构造函数中没有可调用的Box
构造函数。它不能调用剩下的构造函数,因为它需要参数,编译器不能只为您决定传递什么参数。正如您自己发现的,如果您提供对接受参数的Box
构造函数的调用,您的代码将再次编译。
此外,请注意以备将来参考:"它给了我一个错误"不是对问题的充分描述。它会给你一个非常具体的错误,你必须把它包括在你的问题中。错误为:"类Box中的构造函数Box不能应用于给定的类型"
当您删除默认构造函数Box
时,程序中实际发生的情况是,编译器在BoxWeight
构造函数中没有可调用的构造函数。这会给编译器带来混乱,因此它会给您一个错误
但是,当您向接受参数的Box
的构造函数提供调用时,代码编译时不会出现任何错误。