Node:Class precedence list, Previous:Slot description, Up:Inheritance



5.4.4 Class precedence list

A class may have more than one superclass. 1 With single inheritance (one superclass), it is easy to order the super classes from most to least specific. This is the rule:

Rule 1: Each class is more specific than its superclasses.

With multiple inheritance, ordering is harder. Suppose we have

(define-class X ()
   (x #:init-value 1))

(define-class Y ()
   (x #:init-value 2))

(define-class Z (X Y)
   (...))

In this case, the Z class is more specific than the X or Y class for instances of Z. However, the #:init-value specified in X and Y leads to a problem: which one overrides the other? The rule in GOOPS, as in CLOS, is that the superclasses listed earlier are more specific than those listed later. So:

Rule 2: For a given class, superclasses listed earlier are more
        specific than those listed later.

These rules are used to compute a linear order for a class and all its superclasses, from most specific to least specific. This order is called the "class precedence list" of the class. Given these two rules, we can claim that the initial form for the x slot of previous example is 1 since the class X is placed before Y in class precedence list of Z.

These two rules are not always enough to determine a unique order, however, but they give an idea of how things work. Taking the F class shown in Figure 1, the class precedence list is

(f d e a c b <object> <top>)

However, it is usually considered a bad idea for programmers to rely on exactly what the order is. If the order for some superclasses is important, it can be expressed directly in the class definition.

The precedence list of a class can be obtained by the function class-precedence-list. This function returns a ordered list whose first element is the most specific class. For instance,

(class-precedence-list B) => (#<<class> B 401b97c8>
                                     #<<class> <object> 401e4a10>
                                     #<<class> <top> 4026a9d8>)

However, this result is not too much readable; using the function class-name yields a clearer result:

(map class-name (class-precedence-list B)) => (B <object> <top>)

Footnotes

  1. This section is an adaptation of Jeff Dalton's (J.Dalton@ed.ac.uk) Brief introduction to CLOS