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

Abu*_*mad 4 java inheritance protected

我有一个问题,了解受保护的成员继承和可见性.

我知道它在同一个包和子类中是可见的.

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

A.java

package a;

public class A {

    public static void main(String[] args) {

    }

    protected void run() {

    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么最后一个类中的b.run()是不可见的?

sst*_*tan 7

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

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

6.6.2.1.访问受保护的会员:

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

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

还谈到了Codebender关于包裹的评论.请注意,如果C类在与定义A受保护run()方法的类相同的包中定义,则上述规则将不适用,您将能够访问代码中显示的方法.