Avoid instance

I have a POJO set with a common superclass. They are stored in a two-dimensional array of the type superclass. Now I want to get an object from an array and use subclass methods. This means that I have to classify them. Is there a way to do this without using instanceof?

Update: As a specific example: http://obviam.net/index.php/the-mvc-pattern-tutorial-building-games/ See "Add new actions (attack) when the enemy is clicked"

+4
source share
5 answers

If you know that they are of a subclass type, then just produce them directly without checking instanceof .

But placing them in an array filled with a superclass tells the compiler to abandon the information that they really are of a subclass type. Either your superclass should expose these methods (possibly as abstract ones), or your array must be a subclass type (so you don’t tell the compiler to forget about the actual type of objects), or you have to suck it in and do the casting (possibly with a test instanceof ).

The only other notable alternative is that you can experiment with a visitor template that passes the action to the object and allows the object to decide what to do with it. This allows you to override classes to ignore or perform actions depending on their type of execution.

+4
source

Yes - you can do this by inverting the flow: instead of your code doing something when the base class instance is of a specific type, pass the action object to the object and let the object decide whether to execute it or not. This is the main trick of the Visitor Template .

 interface DoSomething { void act(); } abstract class AbstractBaseClass { abstract void performAction(DoSomething ds); } class FirstSubclass extends AbstractBaseClass { public void performAction(DoSomething ds) { ds.act(); } } class SecondSubclass extends AbstractBaseClass { public void performAction(DoSomething ds) { // Do nothing } } AbstractBaseClass array[] = new AbstractBaseClass[] { new FirstSubclass() , new FirstSubclass() , new SecondSubclass() , new FirstSubclass() , new SecondSubclass() }; for (AbstractBaseClass b : array) { b.performAction(new DoSomething() { public void act() { System.out.println("Hello, I'm here!"); } }); } 
+6
source

You can try using a visitor design template. http://en.wikipedia.org/wiki/Visitor_pattern

You should ask yourself why you need to know their type, perhaps this can be replaced by using an abstract method in the superclass, which each of them can implement in accordance with the desired result.

 abstract class A{ abstract void visit(); } class B extends A{ void visit() { print("B"); } } class C extends A { void visit() { print("C"); } } 
+2
source

I would not drop them first.

Actually think about what you are trying to do, and if they should be in the same collection.

If you have something like this

 for(MyObj o : array) { if(o instanceof A) { ((A)o).doA(); } if(o instanceof B) { ((B)o).doB(); } } 

consider this instead

 abstract class MyObj { abstract void doIt(); } class A { void doIt() { doA(); } } class B { void doIt() { doB(); } } 
+1
source

Open the method in the superclass, and then use the override. Provide an empty implementation in the base class so that subclasses can ignore the action if necessary.

0
source

All Articles