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
主要用于授予对子类的访问权限。“如果子类不属于相同的包”-在相同的。。。“父类的受保护方法对子类不可见。”否。从子类访问是受保护的整个点。您可能指的是默认的可见性,
受保护的
访问包括该可见性。