考虑这个简单的java代码:
class A {
private int a = 10;
public void print() {
System.out.println(this.getClass().getName() + " " + a);
}
}
public class B extends A {
public void p1() {
print();
}
public static void main(String... args) {
B b = new B();
b.p1();
}
}
如果要运行代码,则打印的值为B 10。 我的问题是,如果" a"当我们使用" private"修饰符,但方法是,然后现在在B类中有方法print()但是" a"因为它是私有的,所以不是该类的一部分,所以当我们试图通过说" a"的范围来尝试访问它时编译器不会抛出错误。是私人的?
答案 0 :(得分:2)
print
中的class A
class B
可以在public
中找到,因为它class B
而class A
是print
的孩子。< / p>
但class A
中的class A
可以查看a
中的所有字段,因为它是该类的方法。所以 函数可以看到 <script>
function handleAuthClick(event) {
gapi.auth.authorize(
..
}
</script>
<script src="https://apis.google.com/js/client.js?onload=checkAuth">
</script>
</head>
<body>
..
<button id="authorize-button" onclick="handleAuthClick(event)">
Authorize
</button>
,因此可以看到编译过程。
答案 1 :(得分:1)
Field&#39; a&#39;是继承的。它不能直接从B类访问。 只有A类才能访问字段a。
答案 2 :(得分:0)
您将继承与可见性/访问混淆。
a
内部B
属性不可见;但它肯定是继承的,因为它仍然存在,因为B
的实例包含A
(class B extends A
)的实例,以及A
的实例(print()
方法存在的地方)始终包含a
属性。
答案 3 :(得分:0)
JLS(8.3. Field Declarations)声明:
一个类继承自它的直接超类,并直接超级接口超类和超接口的所有非私有字段,这些字段既可以被类中的代码访问,也不会被类中的声明隐藏。
子类可以访问超类的私有字段 - 例如,如果两个类都是同一个类的成员。 然而,私有字段永远不会被子类继承。
但是,“继承”究竟意味着什么?
它的实际含义是(继承的)方法或字段的名称存在于子类的名称空间中。没有private
方法。它不能在子类的名称空间中命名。
另一方面,超类的私有字段必须存在于子类的实例中。如果它不存在,则在超类中声明的使用私有字段的方法无法正常运行。
但是接下来我们讨论了嵌套类; e.g。
public class Outer {
class A {
private int a;
...
}
class B extends A {
private int b1 = a; // Compilation error
// field 'a' is still accessible!
private int b2 = ((A this).a; // OK!
}
}
(是的......真的!!)
有趣的是,你得到的编译错误是:
Test.java:7: error: a has private access in Test.A
private int b = a;
编译器编写者决定将这种情况描述为对私有变量的访问,而不是访问尚未继承的变量。
我的问题是,如果我们使用“private”修饰符但是方法是“a”不是继承的,那么现在在B类中有方法print()
......是的......
但是“a”不是该类的一部分,因为它是私有的,
没有!
这不是继承对字段的意义。字段a
出现在B
的每个实例中。只是它无法访问。你无法命名。
那么当我们试图通过说“a”的范围是私有来访问它时,编译器怎么不抛出错误?
因为它在那里。
意见:关于private
字段和方法的“继承”的Java定义令人困惑。甚至反直觉。然而,事实就是如此。