Search code examples
javapolymorphismlate-bindingvisitor-pattern

How to overload a method to handle parameter's subclasses in Java?


I have a design issue which I can't just figure out how to solve. Basically I am using a visitor to update instances of a certain class. I want to be able to implement different kind of updates in the future, as extension of my Update class. I also want to be able to update different kinds of objects (all derived from the base class). So I have:

public class Update
{
    public void visit(A obj) { /* generic */ }
    public void visit(B obj) { /* specific for B */ }
    public void visit(C obj) { /* specific for C */ }
}

public class A 
{
    public void accept(Update u) 
    {
        u.visit(this);
    }
}

public class B extends A { /* ... */ }

public class C extends A { /* ... */ }

I have my instances in a List<A>, and I want to apply the most specific update to each object. However, when I try to apply the Update to one of the list's element I always get visit(A) called, instead than more specific ones. I guess that's because it's List<A>, not List<B> or List<C>, but I would expect polymorphism to take care of that. I can't just remove the visit(A) operator, because sometimes it makes sense not to make any distinction between C and B. Do you have any idea about how to solve this without having visit(A) dispatch the message to its overloads?

Thank you


Solution

  • You have to override the accept method

    public class Update
    {
        public void visit(A obj) { /* generic */ }
        public void visit(B obj) { /* specific for B */ }
        public void visit(C obj) { /* specific for C */ }
    }
    
    public class A 
    {
        public void accept(Update u) 
        {
            u.visit(this);
        }
    }
    
    public class B extends A {
        public void accept(Update u) 
        {
            u.visit(this);
        }
    }
    
    public class C extends A { 
        public void accept(Update u) 
        {
            u.visit(this);
        }
    }