简体   繁体   English

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

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

I am calling a super class' protected method from a subclass. 我从子类中调用超类的受保护方法。 Why is this method "not visible"? 为什么此方法“不可见”?

I've been reading some posts such as this one , that seem to contradict the following: 我一直在读一些职位如这一个 ,这似乎违背了以下情况:

Super class: 超级班:

package com.first;

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

Subclass: 子类:

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" ?!?
    }   
}

base is a variable that is not special in any way: it's not part of a class hierarchy and protected access is not available through it. base是一个在任何方面都不特殊的变量:它不是类层次结构的一部分,并且无法通过它进行受保护的访问。 Even though sayHello has access to protected members of Base , it has that access only through inheritance (since it's not in the same package: the protected keyword allows access via both inheritance and package, see the table in this Oracle tutorial ). 即使sayHello可以访问Base受保护成员,它也只能通过继承进行访问(因为它不在同一个程序包中: protected关键字允许通过继承和程序包进行访问,请参阅本Oracle教程中的表)。

Access through this and super is allowed because those are part of the inheritance hierarchy. 允许通过thissuper访问,因为它们是继承层次结构的一部分。

This is the correct behavior. 这是正确的行为。 In fact, Java Language Specification , section , 6.6.2-1, has an example very similar to yours, with a comment that it should not compile. 实际上, Java语言规范的第6.6.2-1节有一个与您的示例非常相似的示例,但有注释,建议不要编译。

The specifics of accessing protected members are detailed in section 6.6.2.1: 第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. C为声明受保护成员的类。 Access is permitted only within the body of a subclass S of C . 仅在C的子类S的主体内允许访问。

In addition, if Id denotes an instance field or instance method, then: 另外,如果Id表示实例字段或实例方法,则:

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 . 如果接入是由有资格的名称Q.Id ,其中Q是一个ExpressionName,则接入是允许的,当且仅当表达式的类型QS或的一个子类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 . 如果通过字段访问表达式E.Id (其中E是主表达式)或通过方法调用表达式E.Id(. . .) (其中E是主表达式)进行访问,则仅当且仅当允许访问时,如果类型ES或的一个子类S

It's the last paragraph that describes why the access should be denied. 这是最后一个段落,描述了为什么应拒绝访问。 In your example, C is Base , S is BaseChild , and E , the type of variable base , is also Base . 在您的示例中, CBaseSBaseChild ,而E (变量base的类型)也是Base Since Base is neither a BaseChild nor a subclass of BaseChild , the access is denied. 由于Base既不是BaseChild也不是一个子类BaseChild ,访问被拒绝。

The keyboard protected is for visibility on the same package. 受保护的键盘用于在同一包装上可见。 If the child class is not of the same package, the protected methods of parent is not visible to the child class. 如果子类不是同一包,则父类的受保护方法对子类不可见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM