私は次の設定をしています:
class Base {};
class ImplA extends Base {};
class ImplB extends Base {};
class ImplC extends Base {};
Base baseFactory(int type) {
switch(type) {
case 0:
return new ImplA();
case 1:
return new ImplB();
case 2:
return new ImplC();
}
Base a = baseFactory(0);
Base b = baseFactory(1);
Base c = baseFactory(2);
List<Base> list = new ArrayList<Base>();
list.add(a);
list.add(b);
list.add(c);
// Somewhere else I have:
interface BaseHandler {
process(ImplA a);
process(ImplB b);
process(ImplC c);
};
今、私ができるようにしたいのは、次のようなものです。
class Processor {
BaseHandler bh;
Processor(BaseHandler bh) {
this.bh = b;
}
void processList(List<Base> list) {
for (Base x : list) {
bh.process(x);
}
}
そして、ユーザーに BaseHandler を実装してもらい、Base リスト内の各要素を操作する Processor を構築できるようにします。
ただし、process(Base)
定義されていないため、これは機能しません。3 つの if ステートメントを追加するだけで簡単に思えるかもしれませんが、Base を拡張するクラスのインスタンスを構築する際に、スイッチのような構造を既に持っています。これを何度も繰り返す必要はないようです。リスト内の各 Base のランタイム クラスを決定し、適切なメソッドを呼び出す中間ステップを記述せずに、このアイデアを実現する方法はありますか (実際には別のスイッチ ケースですが、if になります)。
process
回避策の 1 つは、Impl クラスによって実装する必要がある抽象メソッドを各 Base に持たせることだと思います。ただし、ユーザーは Impl クラスを実装しないため、これは私の状況では受け入れられません。基本的にprocess
、ユーザー定義のコールバックである必要があります。さらに、process
が Impl または Base クラスのメンバーであることは意味がありません。これはまったく関係がないためです。これは、呼び出された型に動的に応答する必要がある別のコールバックです。また、型は常に Base のサブクラスであることが保証されています。