3

假设我有这样的代码:

public interface JustAnInterface {
    void doSomething();
}

public class JustAnInterfaceImplementation implements JustAnInterface {

    @Override
    public static void doSomething() {

    }
}

为什么static doSomething()方法显示错误“方法不会覆盖其超类中的方法”?

4

3 回答 3

7

有人可能会说:因为 @Override 和static根本不在一起。

请记住:多态性仅适用于非静态方法。static表示您的方法“附加”到包含类。

换句话说:您在编译时了解有关静态方法调用的所有信息。但是确定调用哪个覆盖方法的过程发生在运行时。这两个概念在 Java 中不能并存。

于 2017-08-09T10:48:34.700 回答
2

GhostCat 所说的一切都是正确的,但@Override注释不是编译错误的直接原因。

即使删除它,该方法在编译时也是无效的。

您不能通过static在派生类中添加修饰符来覆盖或实现方法,因为覆盖/实现仅对实例方法有效。
尝试不带注释:

public class JustAnInterfaceImplementation implements JustAnInterface {

    public static void doSomething() {

    }
}

你会有一个编译错误比哪个更具体@Override

方法不会覆盖或实现超类型中的方法

你应该得到类似的东西:

覆盖方法是静态的

于 2017-08-09T11:05:31.943 回答
1

静态和非静态方法具有不同的签名,而不仅仅是因为static.

非静态方法偷偷地采用了一个额外的参数 - 的值this

如果您熟悉 python,您可以明确地看到这一点:

class SomeClass(object):
  def doSomething(self):
    pass // whatever method body

在这里,self参数只是一个常规参数:您可以自己调用方法并传递此参数。

在Java中,它是一样的。当您调用该doSomething方法时,您将隐式传递一个参数给它,然后就变成this.

但是,静态方法采用参数。所以实际上,它们不是覆盖等效的,因此您没有正确覆盖该方法。

JVM 必须以某种方式确定应该丢弃该参数。该语言本可以编写为允许这样做,但设计者采取了更简单的方法,即禁止它(因为无论如何都没有充分的理由使用它)。

于 2017-08-09T11:48:48.847 回答