5

ここで達成したいのは、サブクラスがjava.lang.Stringまたはjava.util.HashMapをパラメータとしてquery()メソッドに渡すかどうかを決定することです。インターフェイスは、サブクラスがクエリメソッドを実装する必要があると主張する必要がありますが、どのタイプのパラメータサブクラスを渡したいかは気にしません。

私は次のようなインターフェースを持っています:

interface A<T>{
    public void query(T type);
}

次のような2つのサブクラス:

public class B implements A<String> {
    public void query(String type);
}

public class C implements A<HashMap> {
    public void query(HashMap type);
}

次に、BまたはCを生成するファクトリクラスがあります。

public class AFactory {
    public static A<?> getType(String type)  {
        if(type.equals("B")){
            return new B();
        } else if(type.equals("C")) {
            return new C();
        } 
   }
}

アイデアは、クライアントが次のようにB、Cに依存することなく、以下のようなインターフェイスを使用できるということです。

A instance = AFactory.getType("B");
String a = "test";
instance.query(a); 

私がここで抱えている問題は次のとおりです。eclipseはinstance.query(a)の行でエラーを出します:

タイプAのメソッドquery(capture#2-of?)は、引数(String)には適用できません

問題は、インターフェイスコントラクトが、クエリがStringまたはHashMapを予期している必要があることを認識していないことだと思います。私がこれを解決することしか考えられない方法は、次のような結果をキャストする必要があるということです。

B instance = (B)AFactory.getType("B");
String a = "test";
instance.query(a); 

しかし、これを行うことで、最初は避けたかったA(インターフェイス)だけでなく、Bに依存するようになります。サブクラス(この場合はBとC)に依存せずにこれを行う方法についてのアイデア。

4

2 に答える 2

6

アーネストが言うように、あなたは戻り値をキャストする必要があります—A<String>より具体的ですA<?>

ファクトリメソッドのシグネチャを変更する場合は、ジェネリックスを使用して、自分でキャストする必要をなくすことができます。

public static A<T> getType(Class<T> type) {
    if (type.equals(String.class)) {
        return new B();
    } else if (type.equals(HashMap.class)) {
        return new C();
    }
}

次に、呼び出しコードは次のようになります。

A<String> instance = AFactory.getType(String.class);
String a = "test";
instance.query(a);

これができない場合は、の発信者がgetType()キャストする必要があります。

于 2012-04-17T13:23:19.127 に答える
1

にキャストする必要はありませんB-にキャストしA<String>ます。それはあなたに与えるでしょうquery(String)、しかしあなたの情報源に導入することなくB

@SuppressWarnings("unchecked")
A<String> instance = (A<String>) AFactory.getType("B");
String a = "test";
instance.query(a); 

@SuppressWarnings注釈がないと「安全でない」警告が表示されるため、注釈を追加しました。警告が偽物であることがわかっているので、注釈は問題ありません。

于 2012-04-17T13:17:41.870 に答える