avoid instanceof in Java

inheritance, instanceof, java, oop

Solution

I learned about `Visitor pattern` in Compiler class at university, I think it might apply in your scenario. Consider code below:

public class GameObjectVisitor {

    public boolean visit(GameObject1 obj1) { return true; }
    .
    .
    // one method for each game object
    public boolean visit(GameGroup obj1) { return true; }
}

And then you can put a method in `GameObject` interface like this:

public interface GameObject {

    .
    .
    public boolean visit(GameObjectVisitor visitor);
}

And then each `GameObject` implements this method:

public class GameGroup implements GameObject {

    .
    .
    .
    public boolean visit(GameObjectVisitor visitor) {
        visitor.visit(this);
    }
}

This is specially useful when you've complex inheritance hierarchy of `GameObject`. For your case your method will look like this:

private void allocateUITweenManager() {

    GameObjectVisitor gameGroupVisitor = new GameObjectVisitor() {
        public boolean visit(GameGroup obj1) {
            obj1.setUITweenManager(mUITweenManager);
        }
    };

    for(GameObject go:mGameObjects){
      go.visit(gameGroupVisitor);
   }
}

Problem

I have been told at some stage at university (and have subsequently read in upteen places) that using `instanceof` should only be used as a 'last resort'. With this in mind, is anyone able to tell be if the following code I have is a last resort. I have had a look around on stack overflow but cannot quite find a similar scenario - perhaps I have missed it? ``` private void allocateUITweenManager() { for(GameObject go:mGameObjects){ if (go instanceof GameGroup) ((GameGroup) go).setUITweenManager(mUITweenManager); } } ``` where - `mGameObjects` is an array, only some of which are `GameGroup` type - `GameGroup` is a subclass of abstract class `GameObject`. - `GameGroup` uses interface `UITweenable` which has method `setUITweenManager()` - `GameObject` does not use interface `UITweenable` I suppose I could equally (and probably should) replace `GameGroup` in my code above with `UITweenable` - I would be asking the same question. Is there another way of doing this that avoids the `instanceof`? This code cannot fail, as such (I think, right?), but given the bad press `instanceof` seems to get, have I committed some cardinal sin of OOP somewhere along the line that has me using `instanceof` here? Thanks in advance!

Original source