1

これが私ができるようにしたいことの例です(Javaで):

interface MyInterface<E> {
  public void doSomething(E foo);
}

class MyClass implements MyInterface<ClassA>, MyInterface<ClassB> {
  public void doSomething(ClassA fooA) {
    ...
  }

  public void doSomething(ClassB fooB) {
    ...
  }
}

これを実装しようとすると、コンパイラはMyInterfaceMyClass. MyInterface<ClassA>は とは別の型として扱われると思っていたのですが、そうではMyInterface<ClassB>ないようです。これは非常に便利なように思えるので、エラーに驚いています。

更新: これまでご協力いただきありがとうございました。コメントの 1 つが指摘したように、上記は抽象的です。私が解決しようとしている問題は、オブザーバー クラスが実装するインターフェイスを介して監視するクラスを宣言し、クラス固有のメソッドで監視するオブジェクトの変更を処理するように、オブザーバー パターンを実装することです。このようなアプローチを使用する利点は、クラスが実装するインターフェイスから、監視するオブジェクトのタイプが明確になるため、監視されるクラスのインスタンスへの変更の処理をコンパイラが明示的に実装することをプログラマーに強制することです。したがって、上記の抽象コードは実際には次のようになります。

interface IsObserverOf<E> {
  public void observedDidChange(E foo);
}

class MyClass implements IsObserverOf<Database>, IsObserverOf<Spreadsheet> {
  public void observedDidChange(Database database) {
    ...
  }

  public void observedDidChange(Spreadsheet spreadsheet) {
    ...
  }
}

ここで、MyClass は、Database オブジェクトと Spreadsheet オブジェクトを監視することを宣言します。コンパイラは、理想的な世界では、2 つの異なる observedDidChange() メソッドを実装する必要があることを要求します。

ありがとう。

4

2 に答える 2

5

型消去のため、コンパイルして実行すると、インターフェイスの汎用ビットのパラメータが消えます。Javaに関する限り、MyInterface<ClassA>そして MyInterface<ClassB>同一であり、MyInterfaceコンパイルされたときだけになります。彼らがジェネリックスを実装したとき、あなたが望むケース(メソッドパラメーターの異なるタイプ)を処理することは可能だったと思いますが、Javaはジェネリックパラメーターがリターンタイプに使用されるメソッドをどのように処理しますか?

interface Foo<T> {
    T getSomeObject();
}

問題は、return typeだけが異なるメソッドをオーバーロードできないことです。そのため、のようなことができることの有用性が大幅に制限されますimplements MyInterface<ClassA|ClassB>

于 2009-08-01T23:05:47.287 に答える
5

たぶんあなたはビジターパターン(別名「ダブルディスパッチ」)を探しています。

于 2009-08-01T23:05:51.703 に答える