我试着理解为什么在谈到构造函数时类成员的可访问性之间存在差异。
考虑以下示例:
class A {
static class B {
private B(String s) {}
private void foo() {}
}
static class C extends B {
public C(String s) {
super(s); // call B(String), which is private, and obviously accessible
}
void bar() {
foo(); // compilation error (symbol unknown), as B.foo() is private
}
}
}
私密的A
私人成员不应该从B
访问。对于字段和方法,情况确实如此,但似乎构造函数不遵循相同的规则。
从JLS-8(6.6.1. Determining Accessibility),我们可以阅读:
[...]
只有在类型可访问且声明成员或构造函数允许访问时,才能访问引用类型的成员(类,接口,字段或方法)或类类型的构造函数:
[...]
否则,成员或构造函数被声明为
private
,并且当且仅当它发生在包含成员声明的顶级类(第7.6节)的主体内时才允许访问。构造
任何人都可以解释为什么构造函数可以从C
访问,即使在声明private
时也是如此?
答案 0 :(得分:25)
方法foo()
是私有的,因此您不会继承该方法,也无法直接从C
类调用它。
但是,您可以看到来自B
的私有方法和构造函数,因为所有内容都在同一个包含的类中声明,并使用super
访问它们,这就是super()
工作的原因。
以同样的方式,您可以foo
访问super.foo()
。
请注意,您可以在C
中重新定义新的foo方法,但此方法不会覆盖B.foo()
。
答案 1 :(得分:3)
所以这里的诀窍可能如下:
您无法访问foo
,因为它被声明为私有,因此您不会在C中继承它。
但是,如评论中所述,您可以访问super.foo();
,因为super
是指在同一顶级类中声明的类型(请参阅JLS 6.6.1)。
然后诀窍是,调用super(s)
可以被视为调用super.<init>(s)
,最终与super.foo()
答案 2 :(得分:-2)
在C类中无法访问Foo()方法,因为foo()方法是私有的,而私有方法不能继承到基类。
对于建造者而言,建筑师永远不会被隐藏。另外,我编译了这段代码:
class Vehicle{
int speed=50;
private Vehicle()
{
System.out.println("Private Vehicle constructor");
}
}
public class Bike4 extends Vehicle{
int speed=100;
Bike4()
{
super();
System.out.println("Hi I n constructor");
}
void display(){
System.out.println(super.speed);//will print speed of Vehicle now
}
public static void main(String args[]){
Bike4 b=new Bike4();
b.display();
}
}
获取编译时间错误:Vehicle()在Vehicle中具有私有访问权限 超(); ^ 这清楚地表明无法使用super访问私有构造函数。如果我们能够初始化或访问私有构造函数,那么创建私有构造函数的重点是什么。