Java:打电话给超级班级'受保护的方法来自子类 - 不可见?

时间:2016-03-24 01:11:14

标签: java visibility protected

我打电话给超级班级'受保护的方法来自子类。为什么这种方法"不可见"?

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

超级课程

package com.first;

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

子类:

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

3 个答案:

答案 0 :(得分:10)

base是一个在任何方面都不特殊的变量:它不属于类层次结构,并且无法通过它获得受保护的访问。即使sayHello可以访问Base的受保护成员,但它只能通过继承访问(因为它不在同一个包中:protected关键字允许通过两者进行访问继承和包,请参阅this Oracle tutorial)中的表。

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

答案 1 :(得分:3)

这是正确的行为。实际上,Java Language Specification,section,6.6.2-1,有一个非常类似于你的例子,注释它不应该编译。

访问受保护成员的细节详见6.6.2.1节:

  

6.6.2.1。访问受保护的会员

     

font-family: 'Open Sans', sans-serif;成为声明受保护成员的类。只允许在C的子类S的正文中访问。

     

此外,如果C表示实例字段或实例方法,则:

     

如果访问是通过限定名称Id进行的,其中Q.Id是ExpressionName,那么当且仅当表达式Q的类型为{{1}时才允许访问}或Q的子类。

     

如果访问是通过字段访问表达式S,其中S是主表达式,或是通过方法调用表达式E.Id进行访问,其中E是主要表达式表达式,当且仅当E.Id(. . .)的类型为EE的子类时才允许访问。

这是描述拒绝访问权限的最后一段。在您的示例中,SSCBaseS,变量类型BaseChild也为{{1} }}。由于E既不是base也不是Base的子类,因此拒绝访问。

答案 2 :(得分:-4)

键盘受保护用于查看同一个程序包。如果子类不是同一个包,则子类的受保护方法对子类不可见。