18.3.1 Construction of the class precedence list
To understand how Dylan determines the class precedence list, recall that the define class form for a class includes a list of superclasses. Remember that we defined <aircraft> as follows:
define abstract class <aircraft> (<flying-vehicle>, <ground-vehicle>) ... end class <aircraft>;
Here, we have listed the superclasses as <flying-vehicle> and <ground-vehicle>, in that order.
In creating the class precedence list for a class, Dylan uses the ordering of the list of direct superclasses in the define class form for that class. Dylan relies on the following rules:
1. The class being defined takes precedence over all its direct superclasses.
2. Each direct superclass in the list takes precedence over all direct superclasses that appear later in the list.
These rules establish an ordering of a class and its direct superclasses, called the local precedence order.
We listed <flying-vehicle> before <ground-vehicle> in the list of superclasses of <aircraft>, so, when we apply these rules, we see that, for the <aircraft> class, <flying-vehicle> must have precedence higher than that of <ground-vehicle>. The local precedence order for <aircraft> is as follows:
<aircraft>, <flying-vehicle>, <ground-vehicle>
The local precedence order for a class establishes an ordering of a class and its direct superclasses. But our goal is to produce an overall class precedence list, which establishes an ordering of the class and all its superclasses, direct and indirect. In constructing the class precedence list for a class, Dylan follows two steps:
1. Construct the local precedence order for the class and its direct superclasses, based on the order in which the direct superclasses appear in the define class form for the class.
2. Construct the overall class precedence list for the class by merging the class's local precedence order with the class precedence lists of the class's direct superclasses.
Notice that this procedure is recursive! But it is guaranteed to terminate, because no class can be its own superclass.
The resulting class precedence list must be consistent with the local precedence order of the class, and with the class precedence list of each direct superclass. If class <a> precedes class <b> in the class precedence list, then <b> cannot precede <a> in either the local precedence order or the class precedence list for any direct superclass. Because of the recursive procedure for constructing it, the class precedence list must be consistent with the local precedence orders and class precedence lists of all the class's superclasses, rather than just with those of the direct superclasses.
We can now see how Dylan computes the class precedence list for the <B707> class:
1. Construct the local precedence order for <B707> and its only direct superclass, <commercial-aircraft>. The result is as follows: <B707>, <commercial-aircraft>.
2. Merge the local precedence order with the class precedence list of the only direct superclass, <commercial-aircraft>.
Dylan must now use these rules, recursively, to compute the class precedence list of <commercial-aircraft>. In doing so, Dylan must compute recursively the class precedence list of the only direct superclass of <commercial-aircraft>: <aircraft>. This process continues until Dylan has recursively computed the class precedence lists for all superclasses of <B707>. Finally, Dylan finishes constructing the class precedence list for <B707> itself. Table 18.1 shows the results.
One implication of this procedure is that, if a class inherits a superclass via two different paths, the superclass in common must have precedence lower than that of any of its subclasses. For example, the <object> class is a superclass of
every class (except itself). This class must have lower precedence than any of its subclasses, so it appears last in every class precedence list. The class precedence list is consistent with the rule that a subclass is more specific than are any of its superclasses.




