Java 为什么此受保护成员在子类中不可见

Java 为什么此受保护成员在子类中不可见,java,inheritance,protected,Java,Inheritance,Protected,我在理解受保护成员的继承性和可见性时遇到问题 我知道它在相同的包和子类中是可见的 但在下面的代码中,它在子类中不可见 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 { p

我在理解受保护成员的继承性和可见性时遇到问题

我知道它在相同的包和子类中是可见的

但在下面的代码中,它在子类中不可见

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()是不可见的?

这是因为类
C
可以从它自己的继承树中看到
A
受保护的方法。但是不允许从不同的继承树访问另一个类(
B
)的
A
受保护方法
C
不是
B
继承树的一部分(我的意思是,它不是
B
的父级),因此该行为是正常的

编辑:根据要求添加文档参考

:

如果访问是通过字段访问表达式
E.Id
,或方法调用表达式
E.Id(…)
,或方法引用表达式
E::Id
,其中
E
是主表达式(
§15.8
),然后当且仅当
E
的类型为
S
S
的子类时,才允许访问

将上述内容应用于这种情况,因为变量
b
不是
C
的实例或
C
的子类,所以不允许访问受保护的方法
b.run()


同时也要解决Codebender对软件包的评论。请注意,如果
C
类与
A
类在同一个包中定义,其中定义了受保护的
run()
方法,则上述规则将不适用,您将能够访问代码中所示的方法。

什么是
run()的访问修饰符
?你能用一个官方文档链接来解释这一点吗?由于B和C在同一个包中,并且受保护的字段可以在同一个包中访问,这似乎有点奇怪。C扩展了B,这是同一个问题。从文档中添加了更具体的细节。希望能为你澄清一些事情。