覆盖 Java 中的受保护方法
Posted
技术标签:
【中文标题】覆盖 Java 中的受保护方法【英文标题】:Overriding protected methods in Java 【发布时间】:2011-08-04 00:07:03 【问题描述】:Test.java
package a;
import b.B;
public class Test
public static void main(String[] v)
new A().test();
new B().test();
A.java:
package a;
public class A
protected void test()
B.java:
package b;
public class B extends a.A
protected void test()
为什么new B().test()
会报错?这不会违反可见性规则吗?
B.test()
在Test
中是不可见的,因为它们位于不同的包中,但它拒绝调用可见的B
超类中的test()
。
如果能提供 JLS 相应部分的链接,我们将不胜感激。
【问题讨论】:
“给出错误” .. 你能说得更具体点吗? @Kevin 他在问为什么他不能调用他可以访问超级方法的方法。 @Jeremy:它拒绝编译:“a/Test.java:10: test() has protected access in b.B” @Kevin:阅读问题:“这不违反可见性规则吗?” @Jeremy 错误(在这种情况下)相当明显:这是一个编译时错误,说B().test()
对 a.Test.main(String[])
不可见。
【参考方案1】:
这里是 protected
关键字上的 JLS:
JLS protected description 和 JLS protected example。
基本上protected
修饰符意味着您可以访问给定类的子类中的字段/方法/ ... 1) 和 2) 从同一包中的类。
因为 2) new A().test()
有效。但是new B().test()
不起作用,因为B
类在不同的包中。
【讨论】:
【参考方案2】:这不是继承在 Java 中的工作方式。
如果一个方法被覆盖,而被覆盖的方法是不可见的,那么尝试调用它是一个编译时错误。
您似乎期望 Java 会自动回退到超类中的方法,但事实并非如此。
稍后我将尝试挖掘 JLS,以了解为什么不这样做......
【讨论】:
【参考方案3】:问题是在编译时你告诉 Java 你想访问一个类的受保护成员,而你没有这样的访问权限。
如果你这样做了;
A a = new B();
a.test();
然后它会工作并且被覆盖的方法将运行,因为在编译时Java会检查您是否可以访问A。在运行时,提供的对象具有适当的方法,因此B test() 方法会执行。动态绑定或后期绑定是关键。
【讨论】:
【参考方案4】:是的,覆盖受保护的方法是可能的。
class A
protected void f()
SOP("A");
class B extends A
protected void f()
SOP("B");
public static void main(String...args)
B b=new B();
b.f();
输出:B
【讨论】:
以上是关于覆盖 Java 中的受保护方法的主要内容,如果未能解决你的问题,请参考以下文章
Java - 为啥另一个包中的子级无法通过父级引用访问父级的受保护方法?