为什么这个受保护的成员在子类中不可见

Why this protected member is not visible in the subclass

我无法理解受保护成员的继承和可见性。

我知道它在同一个包和子class中可见。

但是在下面的代码中它在子class中是不可见的。

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
    }
}

为什么最后class中的b.run()不可见?

这是因为 class C 可以从其 own[= 中看到 A 的受保护方法53=]继承树。但是不允许从 another class (B) 访问 A 的受保护方法不同的继承树。 C 不是 B 继承树的一部分(我的意思是它不是 B 的父级),因此行为是正常的。

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

6.6.2.1. Access to a protected Member:

If the access is by a field access expression E.Id, or a method invocation expression E.Id(...), or a method reference expression E :: Id, where E is a Primary expression (§15.8), then the access is permitted if and only if the type of E is S or a subclass of S.

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

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