Question:
I implement it for the first time, and something didn't work.
public interface FieldVisitor {
Object visit(Field field);
}
And these are the methods from the implementation:
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());
....
}
};
I call it like this:
public Node getFieldFor(Field field) {
return (Node) factory.visit(field);
}
It can be seen that objects of different classes are coming:
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
However, as you can see, I only get into the method for the superclass. In general, as I understood what type of pointer, such a function is called. How can I change this behavior? So that the function is called for the actual type, or am I stupid somewhere with the pattern?
Answer:
Because it’s not like that at all.
First, the visitor interface must declare methods for all classes in the hierarchy.
public interface FieldVisitor {
Object visit(PresetField field);
Object visit(StringField field);
...
}
Secondly, the ancestor of the hierarchy declares an abstract accept method, in which a visitor is accepted
class Field {
...
public abstract void accept(FieldVisitor visitor);
...
}
Thirdly, specific such descendants implement / override the acceptor method in such a way that the visitor method is called for the required (own) class
class StringField {
...
@Override
public abstract void accept(FieldVisitor visitor) {
visitor.visit(this); // вызов visit(StringField field)
}
...
}
Finally, the visitor can visit the hierarchy, having previously implemented the visitor's interface by calling the acceptor
...
field.accept(new FieldVisitor() {
@Override
Object visit(PresetField field) {
...
}
@Override
Object visit(StringField field) {
...
}
});
...
Thanks to polymorphism, the accept of a particular class is called, which in turn calls its "own" overloaded visitor method.