#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 конкретного класса, который в свою очередь вызывает "свой" перегруженный метод визитёра.
Комментариев нет:
Отправить комментарий