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

5

我有一个问题,不太理解受保护成员继承和可见性。

我知道在同一软件包中和子类中可以访问它们。

但是在以下代码中,在子类中无法访问它们。

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

run() 的访问修饰符是什么? - Scott
1个回答

7
这是因为类C可以从其自己的继承树中访问A的受保护方法。但是,它不允许从不同的继承树中访问A的受保护方法,例如另一个类B。由于C不是B的继承树的一部分(也就是说,它不是B的父类),因此这种行为是正常的。

编辑:添加所请求的文档参考

6.6.2.1. 访问受保护成员

如果访问是通过字段访问表达式 E.Id,或方法调用表达式 E.Id(...),或方法引用表达式 E :: Id 进行的,其中 E 是一个主表达式(§15.8),则只有当 E 的类型为 S 或 S 的子类时,才允许访问。将上述内容应用于此案例,因为变量 b 不是 C 类的实例或 C 类的子类,所以不允许访问受保护的方法 b.run()。还要回答 Codebender 的关于包的评论。请注意,如果 C 类在与定义受保护的 run() 方法的 A 类相同的包中定义,则上述规则不适用,您可以按照代码中显示的方式访问该方法。

你能提供一个官方文档链接来解释这个问题吗?由于B和C在同一个包中,并且受保护的字段可以在同一个包中访问,所以这似乎有点奇怪。 - Codebender
1
C继承B怎么样?这是同样的问题。 - Abu Muhammad
从文档中添加了更具体的细节。希望这能为您澄清事情。 - sstan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接