3

我很困惑为什么不允许以下内容:

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)方法,但我目前仅限于在对象已经被实例化的情况下才能调用该方法,哪种方式违背了目的......


*更新:*感谢您的回答,我现在更好地理解了。基本上我不应该试图让一个实用程序类(或一个工厂类)实现一个接口(或者至少不是以这种方式)......

4

4 回答 4

9

在 Java 中调用静态方法需要您指定确切的类型。不可能多态地调用静态方法,因此不需要@Override.

请注意,这种方法并非在所有语言中都通用:例如,您可以覆盖Objective-C 中的类方法,Apple 的可可框架很好地利用了这种机制来自定义它们的“工厂”类。但是,在 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 设计者决定不提供这个“魔法”。

于 2012-07-02T15:34:14.970 回答
1

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

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

现在我想用MyInterface(class A) 的实现来调用这个方法,但是由于我不能传递类本身,所以我需要传递一个对象:

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

现在在类foo的实例上调用static覆盖的内部。所以现在我坚持创建一个对象只是为了调用一个静态方法。getInstanceA

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

于 2012-07-02T15:41:13.777 回答
0

因为实现接口使实现者成为接口的类型。这意味着实例需要具有由类型定义的方法,而不是实例的类。

换一种方式,

public void mymethod

public static void mymethod

不是相同的方法声明。它们是完全不同的。如果mymethod在接口上定义,则具有第二个定义根本不满足实现接口。

于 2012-07-02T15:34:23.740 回答
0

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

于 2012-07-02T15:39:55.013 回答