Next: , Previous: Metaobjects and the Metaobject Protocol, Up: The Metaobject Protocol


9.20.2 Terminology

It is assumed that the reader is already familiar with standard object orientation concepts such as classes, objects/instances, inheritance/subclassing, generic functions and methods, encapsulation and polymorphism.

This section explains some of the less well known concepts and terminology that GOOPS uses, which are assumed by the following sections of the reference manual.

Metaclass

A metaclass is the class of an object which represents a GOOPS class. Put more succinctly, a metaclass is a class's class.

Most GOOPS classes have the metaclass <class> and, by default, any new class that is created using define-class has the metaclass <class>.

But what does this really mean? To find out, let's look in more detail at what happens when a new class is created using define-class:

     (define-class <my-class> (<object>) . slots)

GOOPS actually expands the define-class form to something like this

     (define <my-class> (class (<object>) . slots))

and thence to

     (define <my-class>
       (make <class> #:supers (list <object>) #:slots slots))

In other words, the value of <my-class> is in fact an instance of the class <class> with slot values specifying the superclasses and slot definitions for the class <my-class>. (#:supers and #:slots are initialization keywords for the dsupers and dslots slots of the <class> class.)

In order to take advantage of the full power of the GOOPS metaobject protocol (see MOP Specification), it is sometimes desirable to create a new class with a metaclass other than the default <class>. This is done by writing:

     (define-class <my-class2> (<object>)
        slot ...
        #:metaclass <my-metaclass>)

GOOPS expands this to something like:

     (define <my-class2>
       (make <my-metaclass> #:supers (list <object>) #:slots slots))

In this case, the value of <my-class2> is an instance of the more specialized class <my-metaclass>. Note that <my-metaclass> itself must previously have been defined as a subclass of <class>. For a full discussion of when and how it is useful to define new metaclasses, see MOP Specification.

Now let's make an instance of <my-class2>:

     (define my-object (make <my-class2> ...))

All of the following statements are correct expressions of the relationships between my-object, <my-class2>, <my-metaclass> and <class>.

Class Precedence List

The class precedence list of a class is the list of all direct and indirect superclasses of that class, including the class itself.

In the absence of multiple inheritance, the class precedence list is ordered straightforwardly, beginning with the class itself and ending with <top>.

For example, given this inheritance hierarchy:

     (define-class <invertebrate> (<object>) ...)
     (define-class <echinoderm> (<invertebrate>) ...)
     (define-class <starfish> (<echinoderm>) ...)

the class precedence list of <starfish> would be

     (<starfish> <echinoderm> <invertebrate> <object> <top>)

With multiple inheritance, the algorithm is a little more complicated. A full description is provided by the GOOPS Tutorial: see Class precedence list.

“Class precedence list” is often abbreviated, in documentation and Scheme variable names, to cpl.

Accessor

An accessor is a generic function with both reference and setter methods.

     (define-accessor perimeter)

Reference methods for an accessor are defined in the same way as generic function methods.

     (define-method (perimeter (s <square>))
       (* 4 (side-length s)))

Setter methods for an accessor are defined by specifying “(setter <accessor-name>)” as the first parameter of the define-method call.

     (define-method ((setter perimeter) (s <square>) (n <number>))
       (set! (side-length s) (/ n 4)))

Once an appropriate setter method has been defined in this way, it can be invoked using the generalized set! syntax, as in:

     (set! (perimeter s1) 18.3)