Metaclasses

\oopindex{metaclasses} In a class-based approach objects are organized in taxonomies along the class abstraction. A class describes the semantics of a set of objects and acts as a mould from which to create instances. A class in itself is not an object but a syntactical construct used to describe objects. However, a number of class-based languages like Loops, Smalltalk, CommonLoops and Clos, allow a class to be characterized in a more abstract way by means of a metaclass. Metaclasses, in these languages, are used to implement the behavior of a class regarded as an object, behavior that is embodied in class variables and class methods. In addition, the implementation of a class by means of a metaclass allows the programmer to inspect the properties of a class dynamically. For instance a class may answer to a request whether it supports a particular method.\ftn{ Static members in C++ do not support such reflective capabilities, although library packages exist -- as for example the NIHCL-library  [GOP90] -- that do provide such features for C++. } \oopindex{modeling} From the perspective of object oriented modeling, metaclasses provide the means to capture general properties of the system on a higher level, by defining the appropriate metaclass for a category of classes.

Three-level architecture

In Smalltalk and Loops, the dichotomy between classes and objects gives rise to a three-level architecture based on the distinction between objects, classes and metaclasses. The inheritance and instantiation structure of this architecture is pictured in the diagram below. .so three The diagram embodies two hierarchies, the hierarchy determined by the subclass relation (indicated by the solid arrows), and the hierarchy determined by the instance relation (indicated by the dotted arrows). The diagram contains three system-defined entities, namely Object, Class and MetaClass. Object is the root of the inheritance hierarchy, since every class (including metaclasses) must inherit the functionality of Object. Conversely, every ordinary class is an instance of MetaClass, or a subclass thereof. Metaclasses, such as Class and the user defined ListMetaClass, are instances of the system-defined entity MetaClass. MetaClass has a quite peculiar status in this diagram since (the appropriate arrow is omitted) it must be regarded as an instance of itself. The capability of creating instances ultimately comes from MetaClass. This capability is inherited by both the (system-defined) metaclass Class and all user defined metaclasses.\ftn{ In Smalltalk, the user is not allowed to define own metaclasses. In Smalltalk, to each class corresponds a metaclass that is hidden from the user. } In the diagram, the object level contains a single object b1 that is an instance of the class Book. Another user defined class is the class Point, which is an instance of Class and a subclass of the class Object. The architecture sketched by this diagram has a fixed number of levels, corresponding to the distinct notions of object, class and metaclass. The disadvantage of such an architecture from the point of view of object oriented modeling is that generalizations with respect to the functionality of the system may be taken only one level up above the class level. In principle, one would like to allow an arbitrary number of levels at which such generalizations are possible.

Reflective architecture

\oopindex{reflection} \nop{ The architecture sketched above has a fixed number of levels corresponding to the conceptually distinct notions of object, class and metaclass. } What we need is a view that unifies the notions of object, class and metaclass in a way that allows us to define metaclasses to an arbitrary level. In  [Cointe87] a solution is given that unifies these concepts by taking a class as an object defined by a real class. The key to this solution is to provide a reflective definition of a class, as illustrated in the diagram below. \begin{center} .so reflect \end{center} This diagram pictures that Object is an instance of Class. Class, on the other hand, inherits its behavior from Object but is an instance of itself. \oopindex{postulates} The reflective model introduced in  [Cointe87] is fully described by the following postulates: In other words, these postulates require that Object lies at the root of the inheritance hierarchy since every class is an object as well, and that Class lies at the root of the instantiation hierarchy as it provides the capability of creating new instances. Having Class at the root of the instantiation hierarchy entails a circular definition of Class, since Class must be its own instance. In order to act as an object, a class must have an attribute name that records the class name, an attribute supers that tells from which classes attributes and methods are inherited, an attribute iv that records the local variables of the instances of the class, and an attribute methods that contains the methods defined for objects of the class. In accordance with this discussion, we may instantiate the (metaclass) Class by the reflective pattern below. \yprog{Class}{
    name     supers            iv                           methods
  
   Class    (Object)     (name supers iv methods)     (new ...)
  
} Each class that displays such a reflective pattern may be regarded as a metaclass, since its instance variables reflect exactly the properties of a class. Minimally, a class must support the method new in order to create instances. In the picture below, this scheme is illustrated by using Class as a metaclass for a Point class, that has two points as actual (object) instances. $= \begin{center} .so reflexam \end{center} For each class the instance variables are given in brackets. The class Point is an ordinary instance of Class and need not contain the instance variables of Class. In contrast, a metaclass is created by inheriting from Class. It contains all the instance variables defined for Class. In addition, such a metaclass may contain the properties common to a category of classes. The architecture described allows to define an arbitrary number of metaclasses on top of an ordinary class. It is doubtful, however, whether the use of such a tower of metaclasses will often occur in practice. \nop{ A metaclass, created by inheriting from Class, would contain all the instance variables given for Class. In contrast, the class Point is an instance of Class and need not contain the instance variables of Class The instance variables for each class are given in brackets. }