一般に、避けるべき良い解決策instanceof
は、いわゆるビジター パターンを使用することです。
このパターンでは、追加のインターフェース (ビジター)、実行したいコードを含むその実装、および階層のすべてのクラスに追加のメソッドが必要です。と だけA
でB
なく、より多くの種類がある場合に便利です)。
あなたの場合、次のようになります。
interface Visitor {
void visit(A a);
void visit(B b);
}
class Base {
abstract accept(Visitor v);
}
class A extends Base {
accept(Visitor v) {
v.visit(this);
}
}
class B extends Base {
accept(Visitor v) {
v.visit(this);
}
}
class MyVisitor implements Visitor {
visit(A a) {
doSomethingWithA(a);
}
visit(B b) {
doSomethingWithB(b);
}
}
次のように使用されます。
MyVisitor v = new MyVisitor();
while(iterator.hasNext()) {
Base next = iterator.next();
next.accept(v);
}
利点は、ほとんどのコードを 1 回だけ記述する必要があることです。プログラムの別の場所で A と B を使って別のことをしたい場合は、Visitor の別の実装を書くだけです。これらのクラスに追加する場合と同様Base
に、を変更する必要はありません。A
B
doSomething()
編集:
サブクラスの数が増えた場合は、既存のすべての実装を変更する必要がありますVisitor
。ただし、少なくともコンパイラはそれについて教えてくれます。instanceof
処理句を追加する必要がある場所を忘れてしまう可能性があります。これはせいぜい実行時に検出できますが、訪問者パターンはコンパイル時の安全性を提供します。