Question

I have a baseclass, Statement, which several other classes inherit from, named IfStatement, WhereStatement, etc... What is the best way to perform a test in an if statement to determine which sort of Statement class an instance is derived from?

Was it helpful?

Solution

if (obj.getClass().isInstance(Statement.class)) {
   doStuffWithStatements((Statement) obj));
}

The nice thing about this technique (as opposed to the "instanceof" keyword) is that you can pass the test-class around as an object. But, yeah, other than that, it's identical to "instanceof".

NOTE: I've deliberately avoided editorializing about whether or not type-instance-checking is the right thing to do. Yeah, in most cases, it's better to use polymorphism. But that's not what the OP asked, and I'm just answering his question.

OTHER TIPS

if(object instanceof WhereStatement) {
   WhereStatement where = (WhereStatement) object;
   doSomething(where);
}

Note that code like this usually means that your base class is missing a polymorphic method. i.e. doSomething() should be a method of Statement, possibly abstract, that is overridden by sub-classes.

The answer to your question is instanceof.

However, keep in mind that if your code needs instanceof, it's a sign that something is not right with your design. There are some cases when instanceof is justified, but they are rather exceptions. Usually, if your subclasses need to behave differently, you have to use polymorphism instead of if()s.

Try this:

if (Statement.class.isInstance(obj)) {
    doStuffWithStatements((Statement) obj));
}

since Class.isInstance() method takes an object instance as a parameter.

This is not the way to do things in an object-oriented way, it's a throwback to the old code/data dichotomy. Now that's not necessarily a bad thing (if you know what you're doing) but it should be left to the non-object-oriented languages like C.

With proper design, you don't need that sort of behavior. Instead of the construct:

if (obj.getClass().isInstance(Statement.class)) {
    doStuffWithStatements((Statement) obj));
}

(apologies to benjismith for 'stealing' his code), you should really be making the object itself responsible for its own activities thus:

obj.doStuff();

Then each different obj class will have its own definition for doStuff. That is the right way to do it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top