我找不到像我这样的问题,所以我希望它不是重复的问题。
这又是关于覆盖和隐藏的。我想 - 但我可能错了 - 我都理解。
以下代码的行为符合预期,两种方法都已隐藏。 method1因为是私有(private)方法,私有(private)方法不能重写只能隐藏,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
A method can be declared final to prevent subclasses from overriding or hiding it.
如果我将父类中的 method1 更改为“final”
private final void method1(){ System.out.println("parent");}
一切正常。 编辑开始:我预计会出现编译器错误,指出无法隐藏 final方法,但这并没有发生。 :编辑结束
问题 1:这是否意味着只能隐藏静态方法?在我正在阅读的书中(OCA 学习指南,Jeanne Boyarsky 和 Scott Selikoff 第 252 页),他们明确表示隐藏了一个私有(private)方法。
然后我将Parent类中的method2改成了
public final static void method2(){ System.out.println("static parent");}
现在编译器确实报错了,错误是“Child cannot override method2()”,这很让人困惑,因为我以为我试图隐藏一个方法。
问题二:不应该是“Child cannot hide method2()”吗?
edit start:我很清楚这里没有覆盖,但正如提到的规范所指出的:修饰符 final 防止方法被覆盖或隐藏,这就是我将其放在标题中的原因。 :编辑结束
最佳答案
问题1
Question no 1: does that mean only static methods can be hidden?
Parent.method1()
在 Child
中不可见,也不被 Child
继承,仅仅是因为是 private
。所以 Child.method1()
没有覆盖或隐藏 Parent.method1()
,它只是在 Child
中创建了一个新方法,该方法具有相同的名称、参数和返回类型。
参见 http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.3 :
Note that a private method cannot be hidden or overridden in the technical sense of those terms. This means that a subclass can declare a method with the same signature as a private method in one of its superclasses, and there is no requirement that the return type or throws clause of such a method bear any relationship to those of the private method in the superclass.
问题2
Question no 2: Shouldn't it be "Child cannot hide method2()"?
是的,你是对的。应该是“隐藏”。根据 JLS(http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.2),
If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible to code in C.
“隐藏”是static
方法对static
方法所做的。 “覆盖”是实例方法对实例方法所做的事情。两者不能混合:static
方法不能覆盖或隐藏实例方法,实例方法不能覆盖或隐藏static
方法。
顺便说一句,我的 Eclipse 编译器给出了类似的错误消息:“无法覆盖父级的 final方法”
关于Java - 隐藏重写和修饰符 final,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35179036/