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

Posted

技术标签:

【中文标题】Java - 为啥另一个包中的子级无法通过父级引用访问父级的受保护方法?【英文标题】:Java - Why Child in another package cannot access parent's protected method through parent reference?Java - 为什么另一个包中的子级无法通过父级引用访问父级的受保护方法? 【发布时间】:2020-08-09 16:29:54 【问题描述】:

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

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 2 时会出现NO ERROR,因为ChildClass 认为这个方法继承自ParentClass

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

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

【问题讨论】:

不。未在 ChildClass 中定义。仅在 ParentClass 中定义为受保护。 【参考方案1】:

您看到的错误完全合理。

当您执行以下操作时

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

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

现在,如果你这样做了

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

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

在第 3 行中,您正在访问一个 ChildClass 类实例在 ChildClass 内的方法,因此这是合法的。即使您在ChildClass 中有一个私有方法childMethod,您也可以使用ch.childMethod()

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

请参阅此相关帖子:What is the difference between public, protected, package-private and private in Java?(提示:所述表格中的最后一行)

【讨论】:

明白。总的来说,Protected 比定义上看起来要复杂一些。定义过度简化了它。它与其他访问修饰符不相称。与其说“可以通过在不同包中扩展 ChildClass 来访问受保护成员”的一般性声明,不如说“只能在不同包中扩展 ChildClass 成员中访问自己的(此对象的)受保护成员”。 @DebashishBHARALI 私有方法也会出现同样的问题。如果你有一个带有私有方法bar() 的类型Foo,并且你最终得到var f = someFooType(),其中f 的类型被推断为? extends Foo,那么即使你调用f.bar() 也是一个编译错误'在课堂内Foo

以上是关于Java - 为啥另一个包中的子级无法通过父级引用访问父级的受保护方法?的主要内容,如果未能解决你的问题,请参考以下文章

在一个查询中保存父级和子级(子级对父级有空值引用)

父级中的Java方法占位符在子级中使用[重复]

仅展开父级中的子级 div

React (JSX) 中的子级到父级通信没有通量

javascript 从父级中的子级渲染节点更新

从父级中的子级访问元素标记名