代码之家  ›  专栏  ›  技术社区  ›  Melad Basilius

为什么Java 8接口静态方法不能覆盖对象类方法[duplicate]

  •  0
  • Melad Basilius  · 技术社区  · 8 年前

    我不明白为什么不允许以下情况:

    public interface MyInterface {
      MyInterface getInstance(String name);
    }
    
    public class MyImplementation implements MyInterface {
      public MyImplementation(String name) {
      }
      @Override
      public static MyInterface getInstance(String name) { // static is not allowed here
        return new MyImplementation(name)
      }
    }
    

    我理解为什么接口中的方法不能是静态的,但为什么重写方法不能是静态的?

    我希望所有的类都能实现 getInstance(String name) 方法,但我目前仅限于在对象已经实例化的情况下才能调用该方法,而这种实例化违背了目的。。。


    *更新: * 谢谢你的回答,我现在更明白了。基本上,我不应该试图让一个实用类(或者工厂类)实现一个接口(或者至少,不是以这种方式)。。。

    0 回复  |  直到 13 年前
        1
  •  9
  •   Sergey Kalinichenko    14 年前

    在Java中调用静态方法需要指定确切的类型。不可能以多态方式调用静态方法,从而消除对 @Override .

    请注意,这种方法并不适用于所有语言:例如,您可以覆盖 类方法 在Objective-C和Apple的cocoa框架中,它们很好地利用这种机制来定制它们的“factory”类。然而,在爪哇中,C++和C类类方法不支持多态行为。

    理论上,Java设计人员可以让您通过 static 方法,以防实现不需要从实例访问状态。但同样的行为很容易通过一个微不足道的包装实现:

    public class MyImplementation implements MyInterface {
        public MyImplementation(String name) {
        }
        @Override
        public MyInterface getInstance() { // static is not allowed here
            return getInstanceImpl();
        }
        public static getInstanceImpl() {
            return new MyImplementation(name)
        }
    }
    

    Java编译器本可以为您做同样的事情,但看到一个静态方法实现一个实例方法既不寻常又令人困惑,所以我猜Java设计师决定不提供这种“魔法”。

        2
  •  1
  •   Tudor    14 年前

    静态方法不能受制于多态行为。这没有多大意义。想象一下这个用例,假设你想要的是可能的:

    public void foo(MyInterface i) {
        i.getInstance("abc");
    }
    

    现在,我想用 MyInterface (课堂) A ),但由于我无法传递类本身,我需要传递一个对象:

    A a = new A();
    foo(a);
    

    现在在里面 foo 这个 static 推翻 getInstance 在类的实例上调用 A. .所以现在我只能创建一个对象来调用一个静态方法。

    我的观点是,在大多数多态性用例中,您仍然需要创建一个对象,因为在原始接口中,该方法是一个实例方法。

        3
  •  0
  •   hvgotcodes    14 年前

    因为实现接口使实现者 类型 界面的一部分。这意味着 实例 需要让方法由类型定义,而不是由实例的类定义。

    换句话说,

    public void mymethod

    和

    public static void mymethod

    不是相同的方法声明。它们完全不同。如果 mymethod 是在接口上定义的,使用第二个定义并不满足接口的实现。

        4
  •  0
  •   Iain    14 年前

    答案归结为实现接口意味着什么。当一个类实现一个接口时,这意味着该类的每个实例都将响应接口中的每个方法。当您将该方法实现为静态时,就可以调用该方法 没有 类的一个实例——但这并没有实现继承实现的承诺,即该方法可以在类的每个实例上调用。