在Java中重写受保护的方法

在Java中重写受保护的方法,java,methods,overriding,protected,Java,Methods,Overriding,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 cla

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的适当部分。

这里是JLS on
protected
关键字: 和

基本上,
受保护的
修饰符意味着您可以访问字段/方法/。。。1) 在给定类的子类中,2)来自同一包中的类


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

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

如果某个方法被重写,而被重写的方法不可见,则尝试调用它是编译时错误

您似乎期望Java会自动退回到超类中的方法,但事实并非如此


稍后我将尝试挖掘JLS为什么不这样做…

问题是,在编译时,您告诉Java您想要访问类的受保护成员,而您没有这样的访问权限

如果你这样做了

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

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

是的,可以重写受保护的方法

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

“给出一个错误”。。你能说得更具体一点吗?@Kevin他在问为什么他不能调用一个他有权访问超级方法的方法。@Jeremy:它拒绝编译:“a/Test.java:10:Test()在b.b中具有受保护的访问权限”@Kevin:阅读问题:“这不违反可见性规则吗?”@Jeremy错误是(在本例中)非常明显:这是一个编译时错误,表示
B().test()
a.test.main(String[])
不可见。