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の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設計者はこの「魔法のかけら」を提供しないことに決めたと思います。

于 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オーバーライド内はgetInstance、クラスのインスタンスで呼び出されますA。そのため、静的メソッドを呼び出すためだけにオブジェクトを作成することに固執しています。

私のポイントは、元のインターフェースではメソッドがインスタンスメソッドであったため、ポリモーフィズムのほとんどのユースケースでオブジェクトを作成するように制約されることです。

于 2012-07-02T15:41:13.777 に答える
0

インターフェイスを実装すると、実装者がインターフェイスのタイプになるためです。つまり、インスタンスには、インスタンスのクラスではなく、タイプによって定義されたメソッドが必要です。

言い換えれば、

public void mymethod

public static void mymethod

同じメソッド宣言ではありません。それらは完全に異なります。がインターフェイスで定義されている場合mymethod、2番目の定義があるだけでは、インターフェイスの実装を満足させることはできません。

于 2012-07-02T15:34:23.740 に答える
0

答えは、インターフェースを実装することの意味に帰着します。クラスがインターフェースを実装するとき、それはクラスのすべてのインスタンスがインターフェースのすべてのメソッドに応答するという約束です。メソッドを静的として実装すると、クラスのインスタンスなしでメソッドを呼び出すことができますが、それは、クラスのすべてのインスタンスでメソッドを呼び出すことができるという継承実装の約束を満たしていません。

于 2012-07-02T15:39:55.013 に答える