Java - 为什么另一个包中的子项无法通过父引用访问父项的受保护方法?

Java - Why Child in another package cannot access parent's protected method through parent reference?

我有两个 类 在两个不同的包中:

package package1;

public class ParentClass {
    public void testPublic() {
    }

    protected void testProtected() {
    }
}


package package2;

import package1.ParentClass;

public class ChildClass extends ParentClass {
   void test() {
        ParentClass par = new ParentClass();
        par.testProtected(); // Line 1 : ERROR: testProtected() has protected access in ParentClass
        testProtected();     // Line 2 : No error

        ChildClass ch = new ChildClass();
        ch.testProtected(); // Line 3 : No ERROR
        testProtected();    // Line 4 : No error
    }    
}

我能够理解为什么在调用 testProtected() -- Line 2NO ERROR 因为 ChildClass 看到这个方法继承自 ParentClass .

并且能够理解为什么在调用 par.testProtected() -- Line 1 抛出错误 ,因为 par 是一个不同的对象,而当前对象没有访问其他对象的父对象的受保护方法。

但是当引用类型仅为 ChildClass 时,ChildClass 的对象如何访问相同的方法ch.testProtected() -- Line 3(其他对象的父对象的受保护方法)?

您看到的错误完全有道理。

当您执行以下操作时

ParentClass par = new ParentClass();
par.testProtected();

您正在尝试访问 testProtected,就好像它是 ParentClass 的 public API 的一部分一样,就是这样,您正在调用 来自另一个包 ParentClass class 实例的受保护方法。在扩展 class 中调用并不重要,重要的是它是从另一个包中调用的。

现在,如果你这样做

ChildClass ch = new ChildClass();
ch.testProtected(); // Line 3
testProtected();    // Line 4

您不会看到任何错误。为什么?

在第 3 行中,您在 ChildClass 内的 class ChildClass 实例上访问方法,因此这是合法的。即使您在 ChildClass 中有私有方法 childMethod,您也可以完成 ch.childMethod().

在第 4 行中,您通过 this 引用(隐式)访问 testProtected,这意味着它通过 ChildClass 调用方法,这也是合法的。

查看此相关 post:What is the difference between public, protected, package-private and private in Java?(提示:所描述的最后一行 table)