超类引用上的访问修饰符和方法[重复]

Posted

技术标签:

【中文标题】超类引用上的访问修饰符和方法[重复]【英文标题】:Access modifiers & methods on a reference of the super class [duplicate] 【发布时间】:2015-12-13 11:16:41 【问题描述】:

为什么当我在子类中创建超类的引用时,只能从引用中调用公共方法而不是受保护的方法。 (类在不同的包中)

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的访问规则(见我的summary),但我们也需要找到理由。 @bayou.io 感谢您提供的摘要链接:“仅当 B 是 A 的子类,C 是 B 的子类或 C 是​​ B 时才授予访问 obj.m” 如果 C是A?为什么这行不通? @wero 我刚刚从该链接中阅读了答案...我要问的问题可能看起来很愚蠢...如果公共成员和受保护成员都可见,为什么我们可以访问公共字段但不受保护? 嗯,这不是一个小问题。请允许我考虑一下。 @bayou.io 您对下面给出的答案有何看法? 【参考方案1】:

虽然访问修饰符在继承中起着重要的作用,但这个问题不应与继承相混淆。正如@vikss 所说的那样,Super 类不知道下面的继承树,因此我不知道 Huskey 是否可以访问其受保护的成员。 对于你的问题:

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

在运行时,方法由被引用的底层对象解析。这里的底层对象是Dog 超类,我们也使用 Dog 引用它自己来访问它。这缩小了从不允许的包中访问受保护成员的问题。

而且您的代码d.bark(); 位于 main 方法中,该方法本身是与 Huskey 的对象分开的实体。一个更有趣的事实是你甚至不能从 Huskey 类的另一个成员方法调用Dog d = new Dog(); d.bark();这里是访问修饰符),但是你可以很好地直接在同一个成员方法中调用bark() 方法(继承来了)。

希望对你有帮助!

【讨论】:

以上是关于超类引用上的访问修饰符和方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章

修饰符和多态

java修饰符和基本操作符

Java - 访问修饰符和调用哪些方法

Java修饰符和String

php面向对象-修饰符和抽象类和接口

Swift 3:公共访问修饰符和内部访问修饰符之间的区别? [复制]