next up previous contents
Next: Instantiation of Classes Up: Metaclasses Previous: The pattern of

The most General Parts of the Class Hierarchy

 

Let us now illustrate how to construct the most general classes and metaclasses of the class hierarchy. The purpose of this exercise is twofold. First, it allows us to experiment with different variations of the hierarchy. Second, it gives us first hand experience with the problems of dealing with the cyclic dependencies among the fundamental classes in an object-oriented programming environment.

The class hierarchies to be simulated are shown in figure gif.

  
Figure: A sample class and metaclass hierarchy.

A and B

are two sample classes defined by the user. Object is the root of both the class hierarchy and the metaclass hierarchy. As in Smalltalk, I will assume that the metaclass hierarchy is parallel with the class hierarchy. As a matter of naming, a metaclass of a class X is called X-class . Furthermore the class class-class

is an abstract class, which is a superclass of all metaclasses. Metaclass is the class of the metaclasses (i.e., the metaclasses are considered as instances of metaclass .) In turn, metaclass

is considered to be an instance of itself.

In appendix gif the full details of the classes and the metaclasses are listed. Here I will only concentrate on the following aspects:

  1. The handling of the cyclic dependencies among the classes.
  2. The implementation of a class instantiation method, new , in class-class .
Point number two is postponed to section gif.

As can be seen from figure gif, object is an indirect superclass of object-class . Thus, object must exist at the time object-class is instantiated. On the other hand, object is an instance of the metaclass object-class . Consequently, object-class must exist at the time object is instantiated. This cyclic dependency means that it isn't possible to create object

and object-class in the same way that we later will create, say, A and A-class .

The overall strategy for the construction of the class hierarchy in figure gif can be described in the following way:

  1. A temporary version of the metaclass object-class is defined. In this metaclass definition, there is no link to class-class .

  2. The temporary version of the metaclass object-class from step 1 is instantiated, thereby creating the object, which represents the class object .

  3. The class-class part and the object part of object are created. This is possible because object exists as the result of step 2.

  4. Object is repaired such that its super

    refers to the instance of class-class created in step 3.

In the rest of this section I will show some more details of the construction of the hierarchy from figure gif. Readers who are not interested in these details can skip the rest of this section.

First, the temporary version of the metaclass object-class is defined:

 

(define (object-class-temporary)
 (let ((self nil)  
       (super ()))  ; assigned in the method fix-super

   (define (fix-super super-part)
      (set! super super-part)
      'done)

   (define (instance-description)
     (let ((self nil)    
           (super ())   ; empty list because root of hierarchy
       ...)))

  ...
  (set! self outer-dispatch)
  self))

The method fix-super is supposed to be activated on an instance of object-class-temporary , in order to make the connection to the more general parts of an object-class instance. Class-class is defined in the following way:

 

(define (class-class)
  (let ((self nil)  
        (super (new-instance-part object)))

    (let ((instances () ))  ;; a list of instances made by new

      (define (new)  
         )  ; described in section 5.3

      ...

      (set! self outer-dispatch))
      self))

We are now in a position where we can create the class object by instantiating the temporary metaclass object-class-temporary

(define object (new-part object-class-temporary)) 
(send object 'fix-super (new-part class-class))
(virtual-operations object)

The first line sets up an object without a link to a super class. This creates an object which among other messages responds to fix-super . Next we send the message fix-super to object with an instance of class-class as a parameter. Hereby the super part of object becomes a class-class part.

When we in the following instantiate object-class

(in the process of instantiating a ``user defined'' metaclass) we certainly expect the instantiation to have an object -part, a class-class -part, and an object-class part. Therefore we substitute the definition of object-class-temporary

with

 

(define (object-class)
  (let ((oc (new-part object-class-temporary)))
    (send oc 'fix-super (new-part class-class))
    oc))


next up previous contents
Next: Instantiation of Classes Up: Metaclasses Previous: The pattern of



Kurt Noermark
Wed Mar 6 10:30:05 MET 1996