The basic idea behind my simulation of multiple inheritance is to let the variable super
refer to a list of ``super object parts'' instead of only one part, as in the single inheritance case.
(define (class-name)
(let ((super (new-part-list super-class-name ...))
(self nil))
(let ((instance-variable init-value)
...)
(define (method formal-parameter ...)
method-body)
...
(define (dispatch message)
(cond ((eqv? message selector) method)
...
(else (method-lookup super message))))
(set! self dispatch))
self))
The only difference between this template and the class template
shown in chapter is that new-part
has been
replaced with new-part-list
, which takes a variable number
of super classes as parameter. New-part-list
is a mapping of
new-part
on the list of super classes.
Figure: The sharing of parts in a ``diamond'' of four classes.
(define (new-part-list . super-class-list) (mapcar new-part super-class-list))
Furthermore, it is necessary to change the procedure method-lookup such that it can handle the case where a method is searched for in a list of classes:
(define (method-lookup objects message) (cond ((procedure? objects) (objects message)) ((null? objects) ()) ((pair? objects) (let ((leftmost-method ((car objects) message))) (if leftmost-method leftmost-method (method-lookup (cdr objects) message)))) (else (error "Inappropriate objects in method-lookup: " objects))))
This version of method-lookup
realizes a left-to-right,
depth-first search in the super object parts. Notice that the new version of
method-lookup
is an extension of method-lookup
from
section .
If self
is interpreted along the lines described in section
, the methods called set-self
must be sure
to propagate the set-self!
message to each of the
super parts of the actual object part.
There are two problems with this simple approach to the handling of classes with multiple superclasses:
In the following
section I will describe how the first problem can be solved.
It will be assumed that objects are represented as
precedence lists of object parts, as described
in section .
The precedence list representation of objects
does not directly solve problem number one, but the needed mechanism
is closely akin to the precedence list mechanism.
In section I will do the actual construction
of the precedence list representation of objects in the
multiple-inheritance case. This contribution solves
problem number two from above.
In section
a CLOS-like method combination
technique is elaborated.
And finally in section
I discuss how to
make the method lookup more efficient. This is especially relevant
when method combination is in use.