Java - 隐藏重写和修饰符 final

标签 java methods overriding final method-hiding

我找不到像我这样的问题,所以我希望它不是重复的问题。

这又是关于覆盖和隐藏的。我想 - 但我可能错了 - 我都理解。

以下代码的行为符合预期,两种方法都已隐藏。 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/

相关文章:

Java 方法签名和接口(interface)

Java:为什么不覆盖 "this( )"?

flutter - Flutter 中使用@override 的目的是什么?

c++ - 在 C++ 中重写后如何调用原始函数?

java - 同一个按钮多次点击

java - Apache Tiles - 无法访问 Spring MVC 中自定义 ViewPreparer 中的 bean

java - 我可以向哪些类/实例中注入(inject) CDI 事件?

java - 如何将方法调用到对象数组中?

java - 类似的Java类

java - JUnit 终止子线程