超类引用的访问修饰符和方法

4
为什么我在子类中创建超类的引用时,只能从引用调用公共方法而不能调用受保护的方法?(这两个类在不同的包中)
package pet;

public class Dog {
    protected void bark(){};
    void jump(){};  
    public void lick(){};
}


package other;
import pet.*;

public class Husky extends Dog {
    public static void main(String[] args){ 
        Husky h = new Husky();
        h.bark();     //COMPILES (Husky is a subclass of Dog - Protected method)
        h.jump();     //DOES NOT COMPILE (Different packages - package-private access method)

        Dog d = new Dog();
        d.bark();   //DOES NOT COMPILE WHY?
        d.jump();   //DOES NOT COMPILE (Different packages - package-private access method)
        d.lick();   //COMPILES (Method is public)
    }
}

我的问题是为什么 d.bark() 不能编译?bark方法的访问修饰符是 protected,这使它可以从同一包中的类或子类中访问。那么出了什么问题呢?
如果husky引用能够访问bark方法,按照同样的逻辑,dog引用也应该能够访问bark方法。
所以我只能假设存在Dog引用的问题?

好问题。我们知道protected的访问规则(请参见我的总结),但我们还需要找到相应的理由。 - ZhongYu
@bayou.io 感谢您提供摘要的链接:“只有当B是A的子类,且C是B的子类或C等于B时,才允许访问obj.m”如果C是A的子类呢?为什么这样行不通? - RamanSB
@wero 我刚刚读了那个链接中的答案... 我即将要问的问题可能听起来很愚蠢...如果公共(public)和受保护(protected)成员都是可见的,为什么我们可以访问公共字段(public fields),但不能访问受保护字段(protected fields)呢? - RamanSB
好的,这不是一个简单的问题。请允许我一些时间来考虑它。 - ZhongYu
@SotiriosDelimanolis 当你说我在写 C?在这种情况下 Husky 类是 C 吗?我们能在聊天室里继续这个对话吗? - RamanSB
显示剩余4条评论
1个回答

0

尽管访问修饰符在继承中扮演着重要的角色,但这个问题不应该与继承混淆。正如@vikss所说,超类不知道下面的继承树,因此它不知道Huskey是否可以访问其受保护的成员。

回答你的问题:

Dog d = new Dog();
    d.bark(); 

在运行时,方法由被引用的基础对象解析。这里的基础对象是Dog超类,而且我们也是使用Dog引用来访问它本身。这缩小了访问不允许的包中保护成员的问题。
同时,您的代码d.bark();位于main方法中,它本身是与Huskey对象分开的实体。有一个有趣的事实,您甚至不能从Huskey类的另一个成员方法调用Dog d = new Dog(); d.bark();(这就是访问修饰符),但您可以在同一成员方法中直接调用bark()方法(这就是继承)。
希望能帮到您!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接