18.4.2 Refined rules for method dispatch

In summary, the effect of multiple inheritance on method dispatch is to refine the rule for sorting methods according to specificity:

A method is more specific than another if the type of its specialized parameter is a proper subtype of the type of the other method's specialized parameter. (For definitions of proper subtype, see Section 9.3, page 111.) If one type is not a proper subtype of the other, a method is more specific if the class of its specialized parameter precedes the class of the other method's specialized parameter in the class precedence list of the argument to the generic function. Otherwise, the methods are unordered for that parameter.

If the generic function has more than one required argument, Dylan uses this augmented rule for determining specificity in the usual way for sorting applicable methods with more than one argument. In essence, Dylan orders the applicable methods separately for each required argument, and then constructs an overall ordering by comparing the separate sorted lists. In the overall method ordering, a method is more specific than another if it satisfies two constraints:

1. The method is no less specific than the other method for all required parameters. (The two methods might have the same types for some parameters.)

2. The method is more specific than the other method for some required parameter.

Note that one method might be more specific than another for one parameter, but less specific for another parameter. These two methods are ambiguous in specificity and cannot be ordered. If the method-dispatch procedure cannot find any method that is more specific than all other methods, Dylan signals an error.

Comparison with C++: Multiple inheritance in C++ is different from multiple inheritance in Dylan. In C++, unless a base class is virtual, it is inherited multiple times if there is more than one path to the base class as a result of multiple inheritance. In Dylan, all base classes are effectively virtual.

C++ has nothing like Dylan's class precedence list for determining the precedence of two superclasses, neither of which is derived from the other. There is no implicit ordering of virtual members defined for such classes. C++ also has nothing like Dylan's next-method for invoking the next most specific virtual function. A C++ programmer must often explicitly provide the sort of method dispatch and combination that Dylan implements automatically.

For examples of similar Dylan and C++ programs that use multiple inheritance, see Section B.2, page 390.

Comparison with Java: Java formalizes the concept of a protocol with its interfaces. An interface is like an abstract class and a set of required generic functions. A class that implements an interface must define methods for each of the generic functions specified by that interface. In a sense, an interface is like a specification for multiple inheritance, without the implementation. A class that implements an interface is considered to be of the interface type, but it must implement all the behaviors directly, rather than inheriting them from the interface — which may mean that code has to be duplicated, rather than shared and reused.