为什么构造函数不能被继承?

4

我一直在使用Eclipse Juno学习继承中的构造函数。

当我在子类中按两次ctrl+O时,它会显示继承成员。但是我看到甚至包括超类的构造函数在内的继承成员。

但是据说构造函数不是继承的......

有人能解释一下这种行为吗?


请查看链接:https://dev59.com/kGUo5IYBdhLWcg3w2CaJ。 - user2339071
请在 https://dev59.com/xGMl5IYBdhLWcg3wwZPc#18147860 中查看下面的答案。 - vinod
4个回答

8

5
只有成员可以被继承,构造函数不算成员。
要理解为什么构造函数不会被继承,请考虑面向对象编程中继承的机制使一个对象能够被视为另一个更通用的对象。这要求所有数据成员和方法都被继承。但是,继承的目的并不是允许一个对象以与另一个更通用的对象相同的方式实例化。
这是因为构造函数必须将对象初始化为有效状态,而足以初始化父类对象的有效状态信息可能不足以初始化子类对象的有效状态!
为了解决这个问题,如果构造函数被继承,当你从库扩展一个类时,你必须手动选择不想继承的构造函数。这很麻烦且容易出错,因为当该基类中有更多构造函数的新版本出现时,您自己的类现在也会受到无效初始化(通过泄漏的构造函数),除非您也发布更新。或者可能是在自己的超类中添加构造函数会“破坏”自己的子类,你必须去每个子类中选择排除新的构造函数。换句话说,你代码的有效性与你使用的基类更紧密地耦合。
另一方面,“选择加入”通过显式定义自己的构造函数并将它们与基类连接起来,实际上更有意义,并且对于组件的有效性更安全。这种加入是通过链式调用实现的,即在另一个构造函数的开头调用基类的构造函数。
现在Eclipse(我不使用它,所以我根据你在问题中描述的内容)可能会列出可用于链接的构造函数,因为查找它们是非常常见的情况(除非您调用非常简单或无参数的构造函数)。换句话说,为了方便起见,在继承的成员列表中列出了构造函数,但是严格来说,它们并没有被继承。

1
当一个库添加新方法时,您所描述的情况也会发生。 在您的解释中,没有理由不继承构造函数。(抱歉我眼瞎了) - Orri
1
@Orri 这不一样。对于某些子类型,在第一次构造之前需要比其超类型更多的信息是一个完全合理的设计选择(因为在构造时已经知道该类型)。但是,如果一个方法在操作子类型时需要比操作超类型时更多的信息,则是设计缺陷(违反了LSP原则)。 - Theodoros Chatzigiannakis

1
构造函数是链式的:您编写的每个构造函数最终都必须调用其中一个超类构造函数。例如:
public class MyException extends RuntimeException {
    public MyException(String message) {
        super(message);   // invokes RuntimeException(String) constructor
    }
}

如果有的话,super(...)this(...)构造函数调用必须出现在构造函数中的第一条语句。如果两者都没有指定,则隐式地假定为super(),它将链接到超类的默认构造函数。(如果超类没有默认构造函数,则编译将失败。)

4
构造函数不是类成员,因此它们不会被子类继承,但是可以通过子类调用超类的构造函数。 - Juned Ahsan
1
构造函数不会被继承,它们是被链接的。 - Ravi K Thapliyal

0
构造函数不属于成员,所以它们不会被子类继承,但是可以从子类中调用超类的构造函数。
来源:http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html 使用Ctrl+O的Eclipse方法帮助显示当前类中可以调用的所有方法。因此,父级构造函数也会显示在其中,因为您可以使用“super”调用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接