【问题标题】:Overrided method visibility in JavaJava中重写的方法可见性
【发布时间】:2013-09-30 16:06:31
【问题描述】:

假设我们有一个包“p1”:

package p1;

public class A {
    protected void method() { }
}

...我们还有一个包“p2”:

package p2;

import p1.A;

public class B extends A { }

class Tester {
    static void run() {
        new B().method(); //compile-time error
    }
}

现在,如果我们尝试编译整个示例,我们将停留在标记行并显示编译时错误:编译器只是没有在 B 中看到目标方法。为什么会这样?

【问题讨论】:

标签: java inheritance overriding visibility protected


【解决方案1】:

受保护的方法在扩展基类(甚至在层次结构中)或同一个包内的所有类中都是可见的。您正在尝试在其他包和非扩展类中使用方法。

【讨论】:

  • 但它是从 Tester 类调用的,它不扩展 A(或 B
【解决方案2】:

由于Access ModifierA.method()protectedB extends A,所以存在protected B.method(),但需要注意的是,对于B 类中的protected method()method() 就像一个“类 B 的私有实体”,并且只能从任何对象引用“公共实体”,因此 new B().method() 会产生编译时错误。

要使您的代码正常工作,您可以更改访问修饰符。

package p2;

import p1.A;

public class B extends A {

    @Override
    public void method() {
        super.method();
    }
 }

【讨论】:

  • 谢谢,我明白了。当然,我知道如果我将覆盖的方法标记为公共 - 每个人和任何地方都可以引用它。但仍然......我只是想做出一些逻辑,让我解释一下:1.受保护的方法对于子类和同一包内的类是可见的...... 2. B类“IS-A”类A(因为它扩展了一个) - 所以我假设“B”也有方法(因为“A”有它)并且它的可见性不能通过覆盖来缩小......所以 - 如果“B”有保护“方法” - 为什么不能从同一个包中访问?
  • @IlyaGubarev 是有道理的,但问题是 method() 属于 A 类,它位于不同的包中,因此 Tester 无法访问。
  • @IlyaGubarev 尝试在B 中覆盖protected void method(),它只调用super.method(),这可能允许您从Tester 调用method()
  • 好的,现在我想我已经明白了(“方法”是“A”的一部分,而不是“B”的一部分,即使“B”是-A“A”)。实际上,就像您之前评论的那样,我已经制作了一个覆盖的受保护版本。无论如何,这对我来说更多的是理论上的问题——这只是 javac 的一个令人惊讶的行为,尽管我真的很喜欢 Java 继承规则。感谢您提供有趣的观点。
  • 哇。这是超级愚蠢的。我得出的结论是,包的可见性存在根本缺陷。 (我注意到了这一点,因为我删除了一个“多余的”覆盖并遇到了编译错误......)
【解决方案3】:

超类的受保护方法在子类中变为私有。 如果您真的想从任何地方调用它,然后将其设为公共,或者,如果您仍想保护您的超类方法,请在调用(私有,继承)方法的子类中创建一个公共方法,子类中的内容如下:

public class B extends A { 
      public void callTheMethod(){
             method();
      }
}

这可以很容易地被测试类调用

class Tester {
    static void run() {
        new B().callTheMethod(); //works well
    }
}

【讨论】:

    猜你喜欢
    • 2021-09-02
    • 1970-01-01
    • 2010-09-25
    • 2014-01-13
    • 2022-11-10
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多