java - 为什么这个 protected 成员在子类中不可见

标签 java inheritance protected

<分区>

我无法理解 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 {
    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 的 protected 方法。但是不允许从不同的继承树访问 Aanother 类 (B) 的 protected 方法. 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 或 a 的实例C 的子类,不允许访问 protected 方法 b.run()

同时解决 Codebender 对包的评论。请注意,如果 C 类与 A 类定义在同一个包中,则 protected run() 方法被定义,则上述规则不适用,您将能够访问代码中显示的方法。

关于java - 为什么这个 protected 成员在子类中不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32076355/

相关文章:

java - 谁能告诉我这个递归方法是如何工作的?

ios - SWIFT 如何创建一个 NSCoding 子类并从另一个类调用它?

c# - 如何在后代中禁用派生类中的设计器

java - 为什么 Java 的 AbstractList 的 removeRange() 方法受到保护?

C# 保护域访问

Javadoc 链接到 Oracle 的 API 文档不再有效

java - 如何在java中为数组内的对象属性设置值

java - 为 Android 编程时是否需要指定列表的初始大小?

c++ - 友元是在 C++ 中继承的吗?

scala - Scala 类定义中 protected 关键字的含义是什么?