#java #шаблоны_проектирования
В первый раз реализую, и что-то не заработало.
public interface FieldVisitor {
Object visit(Field field);
}
А это методы из реализации:
private FieldVisitor factory = new FieldVisitor() {
public Object visit(PresetField presetField) {
....
}
public Object visit(StringField stringField) {
....
}
@Override
public Object visit(Field field) {
System.out.println(field.getClass());
....
}
};
Вызываю так:
public Node getFieldFor(Field field) {
return (Node) factory.visit(field);
}
Видно что приходят объекты разных классов:
class com.dma.params.model.field.PresetField
class com.dma.params.model.field.PresetField
class com.dma.params.model.field.NumberField
class com.dma.params.model.field.NumberField
class com.dma.params.model.field.StringField
class com.dma.params.model.field.BooleanField
Однако попадаю как видно только в метод для суперкласса. В общем, как я понял, какой
тип указателя, такая функция вызывается. Я могу как то изменить это поведение? Чтобы
вызывалась функция для фактического типа или я где-то тупанул с паттерном?
Ответы
Ответ 1
Потому что всё совершенно не так. Во-первых интерфейс визитёра должен объявлять методы для всех классов иерархии public interface FieldVisitor { Object visit(PresetField field); Object visit(StringField field); ... } Во-вторых родоначальник иерархии объявляет абстрактный метод accept, в котором принимается визитёр class Field { ... public abstract void accept(FieldVisitor visitor); ... } В-третьих конкретные такие потомки реализуют/переопределяют метод-акцептор таким образом, чтобы вызывался метод визитёра для нужного (своего) класса class StringField { ... @Override public abstract void accept(FieldVisitor visitor) { visitor.visit(this); // вызов visit(StringField field) } ... } Наконец визитёр может посетить иерархию, предварительно реализовав интерфейс визитёра вызовом акцептора ... field.accept(new FieldVisitor() { @Override Object visit(PresetField field) { ... } @Override Object visit(StringField field) { ... } }); ... Благодаря полиморфизму вызывается accept конкретного класса, который в свою очередь вызывает "свой" перегруженный метод визитёра.
Комментариев нет:
Отправить комментарий