【发布时间】:2016-05-12 18:24:51
【问题描述】:
我找不到像我这样的问题,所以我希望它不是重复的。
这又是关于覆盖和隐藏。我认为 - 但我可能错了 - 我都理解了。
以下代码的行为符合预期,两种方法都已隐藏。 method1 因为是私有方法,私有方法不能被覆盖,只能隐藏,method2 因为是静态,静态方法不能被覆盖,只能隐藏。
public class Child extends Parent {
public void method1(){System.out.println("child");}
public static void method2(){ System.out.println("static child");}
}
class Parent{
private void method1(){ System.out.println("parent");}
public static void method2(){ System.out.println("static parent");}
public static void main(String[] args){
Parent p = new Child();
p.method1(); //prints out "parent"
p.method2(); //prints out "static parent"
}
}
如果我阅读它的规格说明:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3
可以将方法声明为 final 以防止子类覆盖 或隐藏它。
如果我将 Parent 类中的 method1 更改为“final”
private final void method1(){ System.out.println("parent");}
一切正常。 编辑开始:我预计会出现编译器错误,说最终方法无法隐藏,但这并没有发生。 :编辑结束
问题 1:这是否意味着只能隐藏静态方法?在我正在阅读的书(OCA 学习指南,Jeanne Boyarsky 和 Scott Selikoff 第 252 页)中,他们清楚地说隐藏了一个私有方法。
然后我将Parent类中的method2改为
public final static void method2(){ System.out.println("static parent");}
现在编译器确实抱怨,错误说“孩子不能覆盖 method2()”,这很令人困惑,因为我以为我试图隐藏一个方法。
问题二:不应该是“Child cannot hide method2()”吗?
编辑开始:我很清楚这里没有覆盖,但正如提到的规范指出的那样:修饰符 final 防止方法被覆盖或隐藏,这就是我把它放在标题中的原因。 :编辑结束
【问题讨论】:
-
你的例子有点混乱,因为method2是在method1之前定义的。为了可读性,您可能需要重新构建:a)首先定义方法 1,然后定义方法 2 和 b)首先定义类 Parent,然后定义类 Child,最后定义一些包含 main 方法的公共类作为测试框架。
-
现在我真正的问题是:“一切正常”是什么意思?请说明您的预期和发生了什么。在覆盖最终方法时,我会期望出现编译器错误 - 你得到那个错误了吗?还是编译器通过了它?你看到被覆盖方法的打印输出了吗?
-
Oracle 教程强烈暗示您不能覆盖
static方法,只能隐藏它:docs.oracle.com/javase/tutorial/java/IandI/override.html -
@penguineer:我改变了方法的顺序,但我保持了类的顺序。因为父类中的 method1 是私有的,所以我不会帮助创建一个包含主要方法的公共类。为了测试最终的修饰符,我需要以这种方式构造它。
-
@Victor Sorokin/penguineer:这里没有发生压倒一切的事情。我编辑了我的帖子以提及这一点。
标签: java methods overriding final method-hiding