Java inherits this behavior from C++. Stroustrup explains why C++ does this
in his _The Design and Evolution of C++_, the answer being that trying to
dispatch on multiple types (the type of "this" plus the types of one or more
arguments) is far ore complicated and difficult to do efficiently than
dispatching based on just one type.
Multimethod dispatch isn't difficult and it can be implemented quite
efficiently - but whereas single dispatch can be O(1) or O(d) in the
_d_epth of the class tree, multimethod dispatch is O(pt) or O(ptd) in
the number of _p_arameters, _t_ypes/classes and _d_epths of the class
trees.
The most common approach to multimethod dispatch seems to be a
discrimination tree:
if (param1 is typeA)
if (param2 is typeX)
:
else
if (param2 is typeY)
:
else
:
else
if (param1 is typeB)
:
else
:
If the runtime data is organized properly, it is possible to have O(1)
type checks even with multiple inheritance. It may not be necessary
to check all the parameters - each test must reduce the set of
possible matches (eventually to one) and a parameter which has the
same type in all the remaining overloads has no discriminating value.
And parameters do not need to be checked in order - the tree can be
arranged so that parameters with the most discriminating value are
checked first.
Java and C++ already perform this kind of discrimination to decide
which overloaded function to call, but the decision is made at compile
time using the parameter's static types.
Lisp generates code for multimethod dispatch at runtime (at the first
call) because Lisp allows runtime modification of classes and runtime
redefinition of methods - a new dispatch tree must be constructed for
a multimethod if any of the classes or overloaded methods involved are
changed. However, Haskell and ML, which don't allow runtime
modification of methods or classes construct their dispatch code at
compile time.
Studies of multimethod use have shown that there are only a few
parameters and types involved in a typical dispatch so the
discrimination tree is usually quite shallow.
George