4

Javaには、クラスXとインターフェースがYあり、次に一連のクラスがありますA1..そして、それが拡張Xおよび実装されYます. A1..An 次に、各クラス(つまり)のラッパー/アダプターを作成しますA1'..An'

ここで、クライアント クラスCで、インターフェイスY( ArrayList < Y >) のインスタンスのリストを受け取ります。

この場所で、リスト内の各インスタンスに対して、リスト内のインスタンスの事実に基づいてAx'(から)クラスの新しいインスタンスを作成したいと考えています。作り置きなどに。A1'..An'YA1A1'

私の疑問は、if.. else if... および (インスタンスの) 構築なしで、どうすればこれを達成できるかということです。どういうわけかここで継承を使用できますか?

いくつかのデザインパターンをチェックしていましたが、どのインスタンスが別のクラスであるかに基づいてクラスを作成する方法を見つけることができませんでした。

ヘルプとアドバイスをいただければ幸いです。ありがとう。

4

6 に答える 6

2
for(Y y : ArrayList < Y >)  
{  
   y.getClass().newInstance();  
}  

あなたの質問を正しく理解していれば...

編集

abstract class X implements Y 
{
    Y getInstance();
}

class A1 extends X
{
    void someMethod()
    {
        getInstance(); // return instance of A1_
    }
}

class A1_ extends A1
{
    Y getInstance()
    {
        return new A1_();
    }
}    

EDIT2

子で親のインスタンスを取得したい場合は、次のことができます

this.getClass().getSuperclass().newInstance();
于 2012-09-20T16:36:42.667 に答える
1

まず、アダプター(A ' 1 .. A'n)を具象インスタンス(A 1 .. A n)に関連付ける方法が必要です。これは、を使用して行うのが最適です。良い方法は、その周りにレジストリを作成することです。Map<Class<?>, Constructor<?>>

public class AdapterRegistry {
    private static final Map<Class<?>, Constructor<?>> adapterMap =
            new HashMap<Class<?>, Constructor<?>>();

    public static void register(Class<?> interfaceClass, Class<?> concreteClass, Class<?> adapterClass) 
            throws NoSuchMethodException {
        // Check for the constructor
        Constructor<?> constructor = adapterClass.getConstructor(interfaceClass);
        adapterMap.put(concreteClass, constructor);
    }

    public static <T, V extends T> T wrap(V v) {
        Class<?> concreteClass = v.getClass();
        try {
            Constructor<?> constructor = adapterMap.get(concreteClass);
            if (constructor != null) {
                return (T) constructor.newInstance(v);
            }
        } catch (Exception ex) {
            // TODO Log me
        }
        return null;
    }
}

次に、アダプターを作成するだけです。

public class Adapter implements Y {
    private Y innerY;

    public Adapter(Y innerY) {
        this.innerY = innerY;
    }

    // Implement Y
}

そして、アダプタを登録します。

AdapterRegistry.register(Y.class, A1.class, Adapter1.class);
AdapterRegistry.register(Y.class, A2.class, Adapter1.class);
AdapterRegistry.register(Y.class, A3.class, Adapter2.class);
// ...
AdapterRegistry.register(An.class, AdapterM.class);

必要に応じて、このように同じクラスに複数のアダプタを登録する方法に注意してください。そうすれば、具象クラスのサブセットが同じように処理される場合、それらすべてに同じアダプターを登録するだけで済みます。

次に、ラッパーを取得します。

for (Y y : yList) {
    Y adapter = AdapterRegistry.wrap(y);
    // Do something with the adapter
}

これには特定の制限があります。

  • 各アダプターには、インターフェースによって具体的なオブジェクトを取得するコンストラクターが必要です。
  • インターフェイスには、変更しようとしているメソッドが含まれている必要があります(Yのタイプとして使用する場合innerYは、インターフェイス以外のメソッドにアクセスできるようにこれを変更できますが、キャストを行う必要があります)。

AdapterRegistryジェネリックスを使用しているため、プログラムの他の部分でも使用できます。

コードに問題があり、理解できない場合はお知らせください。

于 2012-09-20T17:08:21.383 に答える
1

作成しますHashMap<Class<Y>, Class<?>>。AnとA'nごとに、リレーションを作成しますmap.put(An.class, A'n.class)

次に、objArrayListのそれぞれについて、A'クラスを取得しますClass aa=map.get(obj.getClass())。次に、クラスaaのインスタンスを、aa.newInstance()(およびsetterを介して渡すobj)またはリフレクションを使用する(およびobjパラメーターとして渡す)コンストラクターを使用して作成します。

于 2012-09-20T16:45:25.843 に答える
1
for(Y y : ArrayList < Y >)  
{  
  Class<?> clazz = Class.forName(y.getClass().getName()+"Adapter");
  YAdapter ya = (YAdapter)clazz.newInstance();
}

両方の答えを混ぜ合わせます。

于 2012-09-20T16:42:40.013 に答える
1

メソッドを使用Class.forName()してラッパーを作成できます。クラス A1..AN とラッパーのクラス名の間のマッピングは、プロパティまたは XML ファイルにハードコードされているか、または A1...AN クラスに配置された注釈を使用する場合に格納できます。

于 2012-09-20T16:38:14.643 に答える