我打电话给超级班级'受保护的方法来自子类。为什么这种方法"不可见"?
我一直在阅读一些帖子,例如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" ?!?
}
}
答案 0 :(得分:10)
base
是一个在任何方面都不特殊的变量:它不属于类层次结构,并且无法通过它获得受保护的访问。即使sayHello
可以访问Base
的受保护成员,但它只能通过继承访问(因为它不在同一个包中:protected
关键字允许通过两者进行访问继承和包,请参阅this Oracle tutorial)中的表。
允许通过this
和super
进行访问,因为它们是继承层次结构的一部分。
答案 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(. . .)
的类型为E
或E
的子类时才允许访问。
这是描述拒绝访问权限的最后一段。在您的示例中,S
为S
,C
为Base
,S
,变量类型BaseChild
也为{{1} }}。由于E
既不是base
也不是Base
的子类,因此拒绝访问。
答案 2 :(得分:-4)
键盘受保护用于查看同一个程序包。如果子类不是同一个包,则子类的受保护方法对子类不可见。