为什么实现类不能将覆盖方法定义为静态?
我很困惑为什么不允许以下内容:
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)
方法,但是我目前仅限于只有在对象已经被实例化时才能调用该方法哪种方法失败了…
*更新: *感谢您的回答,我现在明白了。 基本上我不应该试图使实用程序类(或工厂类)实现一个接口(或至少,不是这样)…
在Java中调用静态方法需要您指定确切的类型。 无法以多态方式调用静态方法,因此无需@Override
。
请注意,这种方法并非在所有语言中都是通用的:例如,您可以覆盖Objective-C中的类方法 ,Apple的cocoa框架可以很好地利用这种机制来定制它们的“工厂”类。 但是,在Java,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设计者决定不提供这个“魔法”。
静态方法不能受多态行为的影响。 这没有多大意义。 想象一下这个用例,假设你想要什么:
public void foo(MyInterface i) { i.getInstance("abc"); }
现在我想用MyInterface
( A
类)的实现调用这个方法,但由于我不能传递类本身,我需要传递一个对象:
A a = new A(); foo(a);
现在在foo
,在类A
的实例上调用getInstance
的static
重写。 所以现在我不得不创建一个对象来调用静态方法。
我的观点是,在大多数多态用例中你仍然会被限制创建一个对象,因为在你的原始接口中,该方法是一个实例方法。
因为实现接口使实现者成为接口的类型 。 这意味着实例需要具有由类型定义的方法,而不是实例的类。
换一种方式,
public void mymethod
和
public static void mymethod
不是相同的方法声明。 它们完全不同。 如果在接口上定义了mymethod
,则第二个定义不满足实现接口。
答案归结为实现接口的意义。 当一个类实现一个接口时,这是一个承诺,该类的每个实例都将响应接口中的每个方法。 当您将该方法实现为static时,您可以在没有该类实例的情况下调用该方法 – 但这不符合inheritance实现的承诺,即该方法可以在该类的每个实例上调用。