Java:从子 class 调用超级 class' 受保护的方法 - 不可见?

Java: calling a super class' protected method from a subclass - not visible?

我正在从子class 调用超级class' 受保护的方法。为什么这个方法"not visible"?

我一直在阅读一些帖子,例如 this one,它们似乎与以下内容相矛盾:

超级class:

package com.first;

public class Base
{
    protected void sayHello()
    {
        System.out.println("hi!");
    }
}

子class:

package com.second;

import com.first.Base;

public class BaseChild extends Base
{
    Base base = new Base();

    @Override
    protected void sayHello()
    {
        super.sayHello(); //OK :)
        base.sayHello(); //Hmmm... "The method sayHello() from the type Base is not visible" ?!?
    }   
}

键盘 protected 是为了在同一个包上可见。如果子 class 不在同一个包中,则父的受保护方法对子 class.

不可见

base 是一个在任何方面都不特殊的变量:它不是 class 层次结构的一部分,并且无法通过它进行受保护的访问。尽管 sayHello 可以访问 Base 的受保护成员,但它只能通过继承进行访问(因为它不在同一个包中:protected 关键字允许通过继承和包进行访问,请参阅 this Oracle tutorial 中的 table。

允许通过 thissuper 访问,因为它们是继承层次结构的一部分。

这是正确的行为。事实上,Java Language Specification,第 6.6.2-1 节中有一个与您的示例非常相似的示例,并附有不应编译的注释。

访问受保护成员的细节在第 6.6.2.1 节中有详细说明:

6.6.2.1. Access to a protected Member

Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.

In addition, if Id denotes an instance field or instance method, then:

If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.

If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.

最后一段描述了为什么应该拒绝访问。在你的例子中,CBaseSBaseChildE,变量base的类型也是[=27] =].由于 Base 既不是 BaseChild 也不是 BaseChild 的子类,因此访问被拒绝。