В общем, хорошим решением, которое следует избегать 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);
}
Преимущество в том, что у вас естьнаписать большую часть кода только один раз.Если вы хотите сделать что-то другое с A и B в другом месте вашей программы, просто напишите другую реализацию Visitor.Вам не нужно изменять Base
, A
и B
, как если бы вы добавили doSomething()
к этим классам.
Редактировать: Если числоподклассов увеличивается, вам нужно изменить все ваши существующие реализации Visitor
.Тем не менее, по крайней мере, компилятор говорит вам об этом.С instanceof
вы можете забыть место, где вам нужно добавить условие обработки.Самое большее, это можно обнаружить во время выполнения, тогда как шаблон посетителя обеспечивает безопасность во время компиляции.