[英]Why can you not inherit from a class whose constructor is private?
为什么 Java 不允许从构造函数是私有的类继承?
Java 不会阻止使用私有构造函数对类进行子类化。
public class Main {
static class A {
private A() {
System.out.println("Subclassed A in "+getClass().getName());
}
}
static class B extends A {
public B() {
}
}
public static void main(String... ignored) {
new B();
}
}
印刷
Subclassed A in Main$B
它阻止的是无法访问其超类的任何构造函数的子类。 这意味着私有构造函数不能在另一个类文件中使用,包本地构造函数不能在另一个包中使用。
在这种情况下,您唯一的选择就是委派。 您需要调用工厂方法来创建“超级”类的实例并对其进行包装。
因为一个类必须总是调用它的超类构造函数。 如果无法访问超类构造函数,则无法初始化子类。
更多信息: JLS 8.8.10。 防止类的实例化
关于 Brian Roach 的评论:
[对父类构造函数] 的调用仅在您不显式执行并且父类具有公共或受保护的无参数构造函数(或未定义任何在这种情况下存在默认无参数的情况下)时才是隐式的。 它是必需的,因为......这就是语言的工作方式。 孩子 [classes] 必须调用 [他们] 父母的构造函数。
请注意,当您在 Java 中实例化任何类时,总会隐式调用Object
构造函数,因为它是所有类的超类。 它将执行其默认构造函数:
public Object() {
}
来自 JLS 链接的注意事项:
如果隐式声明了默认构造函数,但超类没有可访问的构造函数(第 6.6 节),该构造函数不接受任何参数且没有 throws 子句,则会出现编译时错误。
如果类的构造函数是私有的,则子类不能调用超级构造函数。 因此继承将失败。
如果您有子类,则子类(子类)构造函数有 2 种可能性: 1. 默认构造函数(无参数构造函数):在这种情况下,默认构造函数将自动尝试调用父类构造函数:由于父类构造函数,这将失败是私人的。 2. 参数化构造函数:当您尝试为具有参数化构造函数的子类创建对象时,您需要通过传递参数或不传递参数来强制从子类构造函数调用父类构造函数:这也会失败,因为父构造函数是私人的。
由于子类将具有默认构造函数或参数化构造函数,并且不可能拥有它们中的任何一个,因此您不能拥有具有私有构造函数的父类的子类。
是的,在 Luiggi 的回答中添加了一些东西,在创建单例类时使用了 Java 的这个特性,它只允许创建该类的一个实例。
这是因为,当我们进行继承时,编译器的工作是通过在每个类构造函数的第一条语句中编写 super() 来使所有类与 Object 类建立直接或间接的关系。 当我们将构造函数设为私有时,这意味着不应从类外部访问它,但是当我们进行继承时,编译器将隐式编写这种类型的语句。
class SubClassName extends SuperClassName {
public SubClassName() {
super(); // which will indirectly going to call the Parent class constructor from outside its scope
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.