我很困惑为什么不允许以下内容:
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 :(得分:9)
在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设计者决定不提供这个“魔法”。
答案 1 :(得分:1)
静态方法不能受多态行为的影响。这没有多大意义。想象一下这个用例,假设你想要什么:
public void foo(MyInterface i) {
i.getInstance("abc");
}
现在我想用MyInterface
(类A
)的实现调用此方法,但由于我无法传递类本身,我需要传递一个对象:
A a = new A();
foo(a);
现在在foo
内static
覆盖getInstance
,在A
类的实例上调用。所以现在我不得不创建一个对象来调用静态方法。
我的观点是,在大多数多态用例中,你仍然会被限制创建一个对象,因为在原始接口中,该方法是一个实例方法。
答案 2 :(得分:0)
因为实现接口使实现者成为接口的类型。这意味着实例需要具有由类型定义的方法,而不是实例的类。
换句话说,
public void mymethod
和
public static void mymethod
与方法声明不同。它们完全不同。如果在接口上定义mymethod
,则第二个定义不满足实现接口。
答案 3 :(得分:0)
答案归结为实现接口的意义。当一个类实现一个接口时,这是一个承诺,该类的每个实例都将响应接口中的每个方法。当您将该方法实现为static时,您可以调用方法而无需类的实例 - 但这不符合继承实现的承诺,即该方法可在每个实例上调用上课。