覆盖 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 中的受保护方法的主要内容,如果未能解决你的问题,请参考以下文章

超类中的私有final可以被覆盖吗?

使用 Java 反射访问测试用例中的受保护方法

Java - 为啥另一个包中的子级无法通过父级引用访问父级的受保护方法?

java.lang.Object 的受保护方法如何免受子类的影响?

从另一个类中的受保护方法中获取变量值

Java中的间接子类无法访问的超类中的受保护成员