Java 为什么私有基类构造函数会导致;“隐式超级构造函数不可见”;
若构造函数不在Java中继承,为什么会出现编译错误(隐式超级构造函数A()对于默认构造函数不可见。必须定义显式构造函数)Java 为什么私有基类构造函数会导致;“隐式超级构造函数不可见”;,java,inheritance,constructor,private,Java,Inheritance,Constructor,Private,若构造函数不在Java中继承,为什么会出现编译错误(隐式超级构造函数A()对于默认构造函数不可见。必须定义显式构造函数) UPD。我知道super()是在隐式B构造函数中调用的。但是我不明白为什么它不能用super()访问私有构造函数。所以,如果我们只有私有构造函数,那么类实际上是final?如果B扩展了A,B必须有权访问A构造函数 请记住,构造函数总是调用super()。 因此,这里,B的隐式无参数构造函数不能调用A构造函数。在Java中,如果创建子类的实例,则会隐式创建父类实例。 因此,子类
UPD。我知道
super()
是在隐式B构造函数中调用的。但是我不明白为什么它不能用super()
访问私有构造函数。所以,如果我们只有私有构造函数,那么类实际上是final
?如果B扩展了A
,B
必须有权访问A
构造函数
请记住,构造函数总是调用super()
。
因此,这里,
B
的隐式无参数构造函数不能调用A
构造函数。在Java中,如果创建子类的实例,则会隐式创建父类
实例。
因此,子类构造函数应该对子类
可见,因为它在第一条语句中使用super()
调用父类
构造函数
因此,如果您将父类的构造函数更改为私有类
,子类
无法访问它,也无法创建它自己的任何实例,因此编译器首先根本不允许这样做
但是如果您想在父类中创建私有的默认构造函数,那么您需要在父类中显式创建一个重载的公共的构造函数,然后在子类中使用超级(param)调用
父类的公共重载构造函数
此外,您可能会想private
构造函数有什么用private
构造函数主要用于不希望任何外部类中的其他类对您的类调用new()
的情况。因此,在这种情况下,我们提供了一些getter()
方法来提供out类的对象
例如,Calendar cal=Calendar.getInstance()代码>。这实际上构成了单例设计模式的基础。重要的一点是要理解任何构造函数的第一行是调用超级构造函数。如果您自己不调用超级构造函数,编译器会通过在封面下插入super()来缩短代码
现在,如果在超类中使构造函数私有,上述概念将失败。可以工作
class A {
private A() {
}
public A(int i){
}
}
public class B extends A {
private A(){
super(10);
}
}
或删除私有A(),默认为公共A(),
除非你有另一个构造函数
class A {
}
public class B extends A {
private A(){
super();
}
}
类B
的实例创建类A
的实例,因此B
必须调用super(…)
,如果A
实现了非默认构造函数。因此,构造函数应该受到保护
,以便B
能够调用super(…)
因此,您应该定义一个类B
您可以更改父构造函数的访问修饰符
或者,您可以在父类中定义其他构造函数,该构造函数可由类B
访问并调用该构造函数
您的类B有一个默认构造函数B()-因为您没有显式定义任何其他构造函数。
该构造函数隐式调用其超级构造函数A()。
但是您已经显式地将其中一个私有化为类A,所以您已经显式地声明,包括B在内的任何其他类都不能访问它。我知道super()是在隐式B构造函数中调用的。但我不明白为什么它不能用super()访问私有构造函数。所以,如果我们只有私有构造函数,那么类事实上是最终的吗?@OlegKuts你在这里混淆了一些东西!构造函数不能是
最终的
,事实上,不能重写为构造函数指定的JLS。因此,B
构造函数不是重写A
构造函数,而是调用它。设置A
构造函数private
意味着它不能在A
类之外使用,因此不能在B
类中使用,但是B
构造函数需要A
构造函数,这就是为什么出现错误超级构造函数A()对于默认构造函数是不可见的
:)希望有帮助!也许我应该用逗号…)我的意思是,当所有构造函数都设置为private时,类就成了final。@OlegKuts哦,对不起,我的英语坏了:P实际上这是个好问题,已经回答了;)谢谢,我知道。我的问题是为什么super()不能调用私有构造函数?私有方法不能被重写的原因是一样的吗?super()不能调用Parent
classprivate
构造函数仅仅是因为private
成员只能在同一个类中访问,所以Child
类是一个不同的类,您就不能访问它。@OlegKuts如果这对您有效,您可以将其设置为正确答案(您的最后一个问题的答案是“是”,前提是“final”的意思是“它不能被子类化”。但是,不应该(可能,我认为)假设编译器也会发现这一点,并将类a视为与显式声明为“final”的类a完全相同。)的可能重复
class A {
}
public class B extends A {
private A(){
super();
}
}
public class B extends A {
/*
* The default constructor B means
* public () B {super();}
*/
public B() {
}
}