Java:调用一个超级类&x27;受子类保护的方法-不可见?
我正在从一个子类调用一个超级类的受保护方法。为什么这个方法“不可见” 我一直在读一些帖子,比如,似乎与以下内容相矛盾: 超级类:Java:调用一个超级类&x27;受子类保护的方法-不可见?,java,visibility,protected,Java,Visibility,Protected,我正在从一个子类调用一个超级类的受保护方法。为什么这个方法“不可见” 我一直在读一些帖子,比如,似乎与以下内容相矛盾: 超级类: package com.first; public class Base { protected void sayHello() { System.out.println("hi!"); } } package com.second; import com.first.Base; public class BaseChi
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" ?!?
}
}
子类:
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" ?!?
}
}
键盘受保护用于在同一软件包上查看。如果子类不属于同一个包,则子类看不到父类的受保护方法。
base
是一个在任何方面都不特殊的变量:它不是类层次结构的一部分,无法通过它进行受保护的访问。尽管sayHello
可以访问Base
的受保护成员,但它只能通过继承进行访问(因为它不在同一个包中:protected
关键字允许通过继承和包进行访问,请参见中的表)
允许通过
this
和super
进行访问,因为它们是继承层次结构的一部分。这是正确的行为。事实上,第6.6.2-1节中有一个与您的示例非常相似的示例,其中有一条注释,它不应该编译
第6.6.2.1节详细介绍了访问受保护构件的细节:
6.6.2.1。访问受保护的成员
设C
为声明受保护成员的类。仅允许在C
的子类S
的主体内访问
此外,如果Id
表示实例字段或实例方法,则:
如果访问是通过限定名Q.Id
,其中Q
是表达式名,则当且仅当表达式Q
的类型是S
或S
的子类时,才允许访问
如果访问是通过字段访问表达式E.Id
,其中E
是主表达式,或通过方法调用表达式E.Id(…)
,其中E
是主表达式,则当且仅当E
的类型是S
或S
的子类时,才允许访问
最后一段描述了为什么应该拒绝访问。在您的示例中,
C
是Base
,S
是BaseChild
,E
,变量Base
的类型也是Base
。由于Base
既不是BaseChild
也不是BaseChild
的子类,因此访问被拒绝。我想你是这里唯一注意到Base
只是一个变量的人。不过我想我需要更好的术语。。我知道我想说什么,但我认为有更好的被接受的术语,我现在记不起来了。不同的是,它是同一个类。没有涉及子类。请参阅dasblinkenlight的引文以了解更多详细信息。@StefanDollase,我的阅读方式不同。听起来正确,与您的示例不一样。主要区别在于OP试图使用父对象的实例,就好像它是this
。“如果它当时在另一个班级,那将是非常令人惊讶的。”正如我所说,我对私人的行为并不感到惊讶,而是对受保护的人的行为感到惊讶。因此,问题不在于为什么允许隐私,而在于为什么不允许受保护的隐私。让我们将您的算法示例转移到受保护的版本中,该算法在this
以外的其他实例上使用私有方法:为什么我不能在this
以外的另一个实例上实现使用当前继承层次结构中受保护方法的算法?为什么我不能访问BinaryTreeNode中子节点的父类的受保护方法?可能与此相同:虽然我知道这会阻止通过base
进行访问,但我不知道它如何允许通过super
进行访问。super
不是与base
的类型相同吗?也许我在JLS中遗漏了什么?JLS的另一部分是否允许使用?我找不到允许它的节。@StefanDollase就是这样,super
不是一个字段,它是一个关键字,允许您访问在类中重写的基类的方法。然而,实际的参考是通过此
,而不是通过不同的变量来完成的。为了解释否决票:“the”是一种将字符输入计算机的设备。“受保护是为了在同一个包上的可见性”-在同一个包中,但我离题了protected
主要用于授予对子类的访问权限。“如果子类不属于相同的包”-在相同的。。。“父类的受保护方法对子类不可见。”否。从子类访问是受保护的整个点。您可能指的是默认的可见性,受保护的
访问包括该可见性。