Java中重写的方法可见性
Posted
技术标签:
【中文标题】Java中重写的方法可见性【英文标题】:Overrided method visibility in Java 【发布时间】: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 中看到目标方法。为什么会这样?
【问题讨论】:
因为method()
是protected
? docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
【参考方案1】:
受保护的方法在扩展基类(甚至在层次结构中)或同一个包内的所有类中都是可见的。您正在尝试在其他包和非扩展类中使用方法。
【讨论】:
但它是从Tester
类调用的,它不扩展 A
(或 B
)【参考方案2】:
由于Access Modifier 对A.method()
是protected
和B 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
【讨论】:
以上是关于Java中重写的方法可见性的主要内容,如果未能解决你的问题,请参考以下文章