我在理解受保护成员继承和可见性方面遇到了问题。
我知道它在同一个包和子类中可见。
但是在下面的代码中,它在子类中是不可见的。
A.java
package a;
public class A {
public static void main(String[] args) {
}
protected void run() {
}
}
B.java
package b;
import a.A;
public class B extends A {
public static void main(String[] args) {
B b = new B();
b.run(); // this works fine
}
}
C.java
package b;
import a.A;
public class C extends A{ // it will not work also if extends B
public static void main(String[] args) {
B b = new B();
b.run(); // this is the problem; not visible
}
}
为什么最后一个类中的b.run()是不可见的?
答案 0 :(得分:7)
这是因为类C
可以在 自己的 继承树中看到A
的受保护方法。但是,不允许从其他继承访问 另一个 类(A
)的B
受保护方法树。 C
不属于B
的继承树(据此,我的意思是“它不是B
的父级”,因此行为很正常。
编辑:根据要求添加了文档参考
6.6.2.1. Access to a protected Member:
如果通过字段访问表达式
E.Id
或方法调用表达式E.Id(...)
或方法引用表达式E :: Id
进行访问,则{{ 1}}是主要表达式(E
),然后当且仅当§15.8
的类型为E
或S
的子类时才允许访问强>
将上述情况应用于此案例,因为变量S
不 b
的实例或{{1}的子类},不允许访问受保护的方法C
。
同时解决C
关于包裹的评论。请注意,如果b.run()
类与Codebender
类在同一个包中定义,其中定义了受保护的C
方法,那么上述规则将不适用,您将能够访问代码中显示的方法。