覆盖Java中的受保护方法

时间:2011-04-12 15:23:07

标签: java methods override protected

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中是不可见的,因为它们位于不同的包中,但却拒绝调用test()的超类中的B,这是可见的。< / p>

欢迎链接到JLS的相应部分。

4 个答案:

答案 0 :(得分:12)

在这里,您可以使用protected关键字进行JLS: JLS protected descriptionJLS protected example

基本上protected修饰符意味着您可以从同一包中的类访问给定类 2)的子类中的field / method / ... 1)。

因为2)new A().test()有效。但是new B().test()不起作用,因为类B位于不同的包中。

答案 1 :(得分:7)

这不是继承在Java中的工作方式。

如果方法被覆盖,并且重写的方法不可见,则尝试调用它是编译时错误。

您似乎期望Java会自动回退到超类中的方法,但这种情况不会发生。

我稍后会尝试挖掘JLS为什么不这样做......

答案 2 :(得分:7)

问题是,在编译时,您告诉Java,当您没有此类访问权限时,您希望访问类的受保护成员。

如果你这样做了;

  A a = new B();
  a.test();

然后它将起作用并且重写的方法将运行,因为在编译时Java检查您是否有权访问A.在运行时,提供的对象具有适当的方法,因此执行B test()方法。动态绑定或后期绑定是关键。

答案 3 :(得分:0)

是的,可以覆盖受保护的方法。

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