1

抽象ファクトリ パターンに応じて、次の 2 つのインターフェイスがあります。

public interface GenericObjectInterface<T extends Number>{
    public T getResult();
}
public interface AbstractFactoryInterface{
    public <T extends Number> GenericObjectInterface<T> createGenericObject();
}

GenericObject を実装する抽象クラスがありますが、まだ具体的な型を認識していません (Number に対する一般的な操作のみを行います)。

public abstract class GenericAbstractClass<T extends Number> implements GenericObjectInterface<T>{   } 

次に、汎用パラメーター置換を実行する一連の具象クラスの拡張があります。

public class IntegerObject extends GenericAbstractClass<Integer>{
     public Integer getResult(){}
}
....

ここで、ファクトリの実装内から具象型を構築します。これは GenericObjectInterface を実装していますが、ジェネリック パラメータが失われています。

public class ConcreteFactory{
    public <T extends Number> GenericObjectInterface<T> greateGenericObject(Class<T> c){
         if (c.class.isInstance(Integer.class)){
             IntegerObject obj = new IntegerObject();
             //I would like to return obj
             GenericObjectInterface<T> a = new IntegerObject(); //errror
             GenericAbstractClass<T> a = new IntegerObject(); //errror

             return a;
          }else if (c.class.isInstance(Double.class)){
          }
    }
}

GenericObjectInterface を実装した obj を返したいのですが、どうすればよいかわかりません。どうすればこれを解決できますか?

私はファクトリを抽象化することに慣れていますが、ジェネリックで使用したことはありません。パターンの解釈に誤りがありますか?

4

4 に答える 4

3

メソッドが を返す場合、IntegerObject単に返さないのはなぜGenericObjectInterface<Integer>ですか? パラメーターの型は既にわかっています。

その場合は、ジェネリック パラメータも に追加しAbstractFactoryInterfaceます。

public interface AbstractFactoryInterface<T extends Number> { ... }

public class ConcreteFactory implements AbstractFactoryInterface<Integer> { ... }

実装では、の型はT割り当てから推測されるため、次のようにすることができます。

 GenericObjectInterface<Double> g = new ConcreteFactory().greateGenericObject();

その場合Tは次のようになりますが、内部でDouble使用すると、次のようになります。Integer

GenericObjectInterface<Double> a = new IntegerCell(); 

コンパイラはそれTが常に型であることを保証できないため、Integerその割り当てを行うことはできません。

于 2011-09-23T14:45:14.200 に答える
1

ここでのキャストは完全に問題ありません。の場合c==Integer.class、へのT=Integerキャストは絶対に正しいです。キャストする前にチェックしたので、チェックされたキャストです。したがって、チェックされていない警告は合法的に抑制できます。GOI<Object>GOI<T>T=Integer

于 2011-09-23T19:23:32.503 に答える
1

抽象ファクトリは、具体的な参照ではなく、インターフェイスまたは抽象クラスの参照を返すファクトリ メソッドによって特徴付けられます。型パラメーターには拡張されません。

このように考えてください。これができるはずですか?

public class ConcreteListFactory {
    public <T> List<T> createList() {
        return new ArrayList<String>();
    }
}

発信者がList<Integer>?

ファクトリが生成された型を返すようにする場合は、具象クラスが型パラメーターを受け入れるようにする必要があります。それ以外の場合は、ファクトリ メソッドが a を返すようにしGenericObjectInterface<Integer>ます。

または、メソッドに型トークン ( Integer.class) を受け入れるようにさせることもできます。例えば:

public <T extends Number> GenericObjectInterface<T> createGenericObject(Class<T> clazz) {
    if ( clazz.equals(Integer.class) ) {
        return (GenericObjectInterface<T>) new IntegerObject();
    }
} 

これにより、チェックされていないキャスト警告が発生しますが、安全であることを自分で証明できるため、警告を抑制するか無視することができます。

于 2011-09-23T14:48:25.760 に答える
1

一般に、ジェネリックのタイプを調べて作成するオブジェクトのタイプを決定できないため (T.getClass を実行できない)、ファクトリはジェネリックとして実装されません。これが @Mark の例でクラスが渡される理由です。引数として。

通常、複数のコンクリート工場があると思います。サポートする数値型ごとに 1 つ。

public interface AbstractFactoryInterface<T extends Number> {
    public GenericObjectInterface<T> createGenericObject();
}


class IntegerFactory implements AbstractFactoryInterface<Integer>...
class LongFactory implements AbstractFactoryInterface<Long>...

その後、Map<Class, AbstractFactoryInterface>... を作成できます。

Map<Class, AbstractFactoryInterface> myMap = ...;
myMap.put(Integer.class, new IntegerFactory());
myMap.put(Long.class, new LongFactory ());
于 2011-09-23T15:03:58.880 に答える