超类引用上的访问修饰符和方法[重复]
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()
方法(继承来了)。
希望对你有帮助!
【讨论】:
以上是关于超类引用上的访问修饰符和方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章