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。
允许通过 this
和 super
访问,因为它们是继承层次结构的一部分。
这是正确的行为。事实上,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
.
最后一段描述了为什么应该拒绝访问。在你的例子中,C
是Base
,S
是BaseChild
,E
,变量base
的类型也是[=27] =].由于 Base
既不是 BaseChild
也不是 BaseChild
的子类,因此访问被拒绝。
我正在从子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。
允许通过 this
和 super
访问,因为它们是继承层次结构的一部分。
这是正确的行为。事实上,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 subclassS
ofC
.In addition, if
Id
denotes an instance field or instance method, then:If the access is by a qualified name
Q.Id
, whereQ
is an ExpressionName, then the access is permitted if and only if the type of the expressionQ
isS
or a subclass ofS
.If the access is by a field access expression
E.Id
, whereE
is a Primary expression, or by a method invocation expressionE.Id(. . .)
, whereE
is a Primary expression, then the access is permitted if and only if the type ofE
isS
or a subclass ofS
.
最后一段描述了为什么应该拒绝访问。在你的例子中,C
是Base
,S
是BaseChild
,E
,变量base
的类型也是[=27] =].由于 Base
既不是 BaseChild
也不是 BaseChild
的子类,因此访问被拒绝。