为什么对象的实例会破坏受保护的逻辑?

Why an instance of an object breaks protected logic?

我想弄清楚受保护的访问修饰符在 Java 中的包继承之间是如何工作的。

我有 2 个样本包 p1 和 p2。在 p1 中有一个 class A1,带有一个名为 protectedMember 的受保护访问实例变量,另一个 class B1 只是扩展了 A1。

在 p2 中,我有一个 class A2,它也扩展了 A1。 显然,在 A2 中,我将可以直接访问其父级 (class A1) 的受保护成员,这很好,但我没有问题。

但是,如果我在 A2 中创建了一个方法来启动 A1 或其子 B1 的实例 - 那么我将无法访问该实例的受保护成员。为什么 ?与默认不同的是,受保护的成员可以访问扩展 class.

的包和外部包 classes

那么为什么在 "multiple package" 继承中我可以直接到达父级的受保护成员,而不是通过实例。

请不要回复 "you must do it in parent's package" - 我知道我必须回复。

我想知道为什么?

package p2;

import p1.A1;
import p1.B1;

public class A2 extends A1 {
// please note  - multi package inheritance
    public  void test (){

        /*
        with non of the instances below I can reach the protected member in A1
         */
        A1 a1 = new A1();
        B1 b1 = new B1();
    }

}

因为 A1 (A1 a1 = new A1()) 的实例甚至在扩展它的 类 之外也是可能的。

假设您有:

public class B2 {
  public void test() {
    A1 a1 = new A1();
  }
}

显然访问 A1 的受保护字段应该会失败。

因为这是规定。仅当对象类型为 A2 而不是 A1 或 B1 实例时,才允许从 A2 访问在 A1 或 B1 中声明的受保护成员或方法。 您可以在此处找到更多信息: https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf