Node:Class precedence list, Previous:Slot description, Up:Inheritance
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>)