Abstract and Mixin Classes

While Quintus Objects only supports a limited form of multiple inheritance, its facilities are sufficient for working with so-called mixin classes.

The idea is to construct similar classes by first defining a class that contains the things the desired classes have in common. Typically, this will be an abstract class, which will have no instances itself. Then, provide the features that differentiate the desired classes with a set of mixin classes

Mixin classes that have nothing in common can safely be mixed together, to build the desired classes. The mixin classes will usually be abstract classes, also, because they are too specialized for their instances to be useful on their own.

The date_stamp class defined earlier would make a good mixin class. A similar time_stamp class might be (partially) defined as follows:

     :- class time_stamp =
             [hour:integer,
              minute:integer,
              second:integer].
     
     Self <- create :-
             time(time(Hour, Minute, Second)),
             store_slot(hour, Hour),
             store_slot(minute, Minute),
             store_slot(second, Second).
     

Another mixin class might be used to "register" objects in the Prolog database.

     :- class registry = [name:atom].
     
     Self <- create(Name) :-
             Self << name(Name),
             assert(registered(Name, Self)).
     
     Self <- destroy :-
             Self >> name(Name),
             retract(registered(Name, Self)).
     

The registry mixin class could have been used with the point class to define the named_point class, which was an example from an earlier section.

The ability to send a message to an object's superclass is useful when working with mixin classes. Suppose the definition of a new class begins with

     :- NewClass = OldClass + date + time + registry.
     

where OldClass is some previously defined class that lacks the features provided by the date, time and registry classes. (In fact, they should not have any slot names in common.) Then its create method can be defined by

     Self <- create(Name) :-
             super(OldClass) <- create,
             super(date) <- create,
             super(time) <- create,
             super(registry) <- create(Name).
     

This avoids the need to duplicate the code in the create methods of OldClass and all three mixin classes.