【问题标题】:Why interface methods can't be static in class that implements the interface?为什么接口方法在实现接口的类中不能是静态的?
【发布时间】:2017-08-09 10:35:28
【问题描述】:

假设我有这样的代码:

public interface JustAnInterface {
    void doSomething();
}

public class JustAnInterfaceImplementation implements JustAnInterface {

    @Override
    public static void doSomething() {

    }
}

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

【问题讨论】:

  • 因为接口中定义的方法是非静态的。你的问题基本上是循环的。
  • 静态方法通常没有意义重写。它们属于定义它们的类,并且只属于该类,不构成层次结构的一部分。
  • 方法签名与接口不同。
  • 因为你不能有两个具有相同签名的方法,一个是静态的,另一个是非静态的。请记住,实际上您正在实现接口,因此需要使用非静态接口,因此Interface in = new YourImplementation(); in.interfaceMethod(); 之类的代码将始终有效。
  • 静态方法是“早期绑定的”,静态方法调用的实现在编译时是已知的。对接口方法的调用是“后期绑定”的,实现只在运行时才知道

标签: java inheritance static interface-implementation


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    public class JustAnInterfaceImplementation implements JustAnInterface {
    
        public static void doSomething() {
    
        }
    }
    

    你会遇到比@Override更具体的编译错误

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

    你应该得到类似的东西:

    覆盖方法是静态的

    【讨论】:

      【解决方案3】:

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

      非静态方法偷偷带了一个额外的参数——this的值。

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

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

      这里self参数只是一个普通参数:你可以自己调用方法并传递这个参数。

      在 Java 中,情况大致相同。当您调用doSomething 方法时,您会隐式传递一个参数给它,这将变成this

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

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

      【讨论】:

        猜你喜欢
        • 2011-04-26
        • 2017-12-28
        • 2010-11-18
        • 2011-05-10
        • 2015-02-12
        • 2016-10-06
        • 2012-06-05
        • 2012-05-27
        相关资源
        最近更新 更多