Not really, no. In a language that supports interfaces (either explicitly, or in the form of multiple inheritance with pure virtual classes, like C++), you can always use the following pattern:
interface Fooable {
void foo();
}
abstract class BaseBaz {
public abstract Fooable asFooable();
}
class BazOne extends BaseBaz {
public Fooable asFooable() { return null; } // not a Fooable!
}
class BazTwo extends BaseBaz implements Fooable {
public void foo() { Console.print("I am teh foobar!"); }
public Fooable asFooable() { return this; }
}
// --- snip ---
void runFooOnBaz(Baz baz) {
Fooable fooable = baz.asFooable();
if (fooable == null)
throw new NotFooableException();
fooable.foo();
}
That is, you approach each object by interface, and give the base class a method to return you the object by interface if possible. (There is probably a name for this pattern, but I don't know it - if anyone knows, feel free to edit.)
In a duck-typing language like Python, you'd go a different route: rather than asking whether the object inherits from a given class, you just pretend it does and prepare for failure:
class BazOne(object):
pass
class BazTwo(object):
def foo():
print "I am teh foobar!"
def runFoo(baz):
try:
baz.foo()
except AttributeError:
raise NotFooableError()
However, the latter isn't always possible; reasons as to why not include:
- You might rely on more than one method, and the first call has side effects that you cannot allow unless the second method also exists. Inspecting the object instead of having it run into the exception can usually solve this, but it's not necessarily very pretty.
- You might have to decide on how to treat the object in a way that does not depend on a particular method; for example, you may want to treat
unicode
and string
objects differently.
- The objects might implement a method of the same name, but with different meanings -
hero.save(hostage)
and file.save(filename)
are completely unrelated things, but the method names happen to collide, so just checking whether a method called save
exists can yield false positives.
And then there's the situation where you have to decide on a code path based on more than one object; you can certainly work your way out using the self-describing method approach, or by testing relevant attributes of all the objects, but sometimes, instanceof
is just easier to write, more readable, and more concise, in other words, the pragmatic choice.
instanceof
.instanceof
and Scheme and Racket have ways to easily check if something is of a specified struct/recordinstanceof
, both in theory and in practice. Look up the expression problem for a good example of how it shows; it comes down to ADTs having only a finite, well-known set of alternatives while one can always add new subclasses. Apart from that, I'm confident that the idea ofinstanceof
was not literally taken from FP. It's a simple idea that one can arrive at independently, starting from the general idea of Java-style OO.instanceof
, I agree that it is not the OOP way of dispatching on different types. The OOP way is rather dynamic dispatch.instanceof
is a procedural / functional approach that has been added to several OOP languages as a facility (the OOP solution can get very verbose).