首页 > 解决方案 > 使用子类引用访问包外的受保护成员

问题描述

package pack1;
class A{
   protected void m1(){
      System.out.println("protected modifier");
   }
}

package pack2;
class B extends A{
    public static void main(string[]args){
         B b = new B();//Valid
         b.m1();

        A a = new B();//Invalid
          a.m2();

       A a1 = new A();//InValid
         a1.m1();

   }
}

为什么在访问包外的受保护成员时,我们只需要子类引用。?

为什么我们不能使用父引用来访问受保护的成员(这里 A a = new B())?

我浏览了博客和许多堆栈溢出的答案,但没有找到 WHY? 的任何答案。

那么任何人都可以帮助我知道为什么的答案吗?

标签: javaprotectedaccess-modifiers

解决方案


A由于您仍在子类或包之外,因此不允许您访问。该main方法是static,因此不受类实例的约束B。为了访问A你需要在类里面B,所以在一个非静态上下文中,比如

public class B extends A {
    public void foo() {
        m1(); // Valid call since inside subclass
    }
}

我想你误解了什么static意思。


Java 语言规范protected中描述了详细信息。摘自JLS§6.6.2

对象的protected成员或构造函数可以从包的外部访问,在该包中,仅由负责实现该对象的代码声明它。

让是声明成员C的类。仅允许在 的子类的主体内protected访问。SC

限制甚至超出了您的示例。关键是“负责执行”。将其与以下示例进行比较:

package a;

public class Point {
    protected int x;
    protected int y;
}
package b;

import a.Point;

public class Point3D extends Point {
    public void delta(Point other) {
        other.x += this.x;  // Compile-time error: Cannot access other.x
        other.y += this.y;  // Compile-time error: Cannot access other.y
    }
}

虽然类Point3D是 的子类Point,但它不负责other对象的实现。因此,不允许访问其protected成员。

同样适用

public class B extends A {
    public void foo() {
        A other = new A();
        other.m1(); // Compile-time error
    }
}

因为foo()方法调用所属的当前实例不负责other. 因此,不允许访问。


推荐阅读