为什么不是子类构造函数重写?

时间:2011-04-28 16:43:29

标签: java

我有代码:

class Oak extends Tree {
    public Oak() {
        System.out.println("Oak()");
    }
}
class Tree {
    public Tree() {
        System.out.println("Tree()");
    }
}

class mainClass {
    public static void main(String[] args) {
        Oak a = new Oak();
    }
}

为什么打印

Tree() 
Oak()

而不仅仅是

Oak()

6 个答案:

答案 0 :(得分:6)

Oak是一种Tree,因此必须首先构建对象的Tree部分。因此,将调用默认的Tree构造函数。随后,Oak构造函数可以运行。

这完全等同于在Tree构造函数中显式调用Oak构造函数作为第一个语句:

public Oak() {
    super();
    ...
}

[请注意,构造函数不会“覆盖”。]

答案 1 :(得分:5)

构造函数永远不会被继承,也永远不会覆盖。这意味着,父元素的构造函数将始终在创建子类的实例时执行。因此,您会收到两条消息

答案 2 :(得分:0)

派生类对象构造按基础类子对象构造和派生类子对象构造的顺序进行。

答案 3 :(得分:0)

构造函数将从Root类以向下的顺序调用。构造函数中没有压倒一切的概念。

答案 4 :(得分:0)

构造函数不能被覆盖;覆盖仅适用于非静态,非私有方法。

关于继承,你必须要了解一件重要的事情。它暗示了子类和超类之间的关系。因此,子类的实例是其超类的实例,其中添加了特定于子类的内容。例如,Oak 树。

这意味着Oak对象的一部分是Tree对象。创建Oak对象时,首先创建并初始化对象的超类部分。这涉及调用超类的构造函数(在您的示例中为Tree的构造函数)。之后,将子类部分添加到对象中,为此调用Oak的构造函数。

答案 5 :(得分:0)

创建对象时,必须调用超类的构造函数。您可以显式指定您调用的超类的哪个构造函数,在这种情况下调用无参数构造函数。这就是你打电话给Tree()的原因。如果你没有无参数构造函数,那么就会出现错误:

class Oak extends Tree {
    public Oak() {
        super("Oak Tree"); //Without this line the code won't compile
        System.out.println("Oak()");
    }
}

class Tree {
    public Tree(String name) {
        System.out.println("Tree(" + name + ")");
    }
}

class mainClass {
    public static void main(String[] args) {
        Oak a = new Oak();
    }
}