Java继承概念引用超类构造函数?

时间:2015-12-05 14:25:21

标签: java inheritance

我正在做一个简单的继承程序,但是在做这个程序时我感到很困惑。

这是一个简单的程序:

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(),那么它可以正常工作。我不明白为什么?我知道这个概念非常简单,但我很难理解它。感谢任何帮助。

4 个答案:

答案 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构造函数的调用时,您的代码会编译而不会出现任何错误。