[<<Previous Entry]
[^^Up^^]
[Next Entry>>]
[Menu]
[About The Guide]
Metaclasses
Class(y) v2.4 treats classes as real objects in every sense. They have a
class of their own - the predefined class called Class, or a subclass
thereof.
The Class class is used to create new classes, as can be seen in the v2.4
headers. The information used to create a class remains in existence in
the class object for each class, so classes can be queried at runtime as
to their structure.
Important Note
The operation of metaclasses is not an issue with which most programmers
need be concerned. Metaclasses are necessary to create a consistent,
object-oriented, open architecture which allows Class(y) to be cleanly
enhanced, extended and integrated with other object-oriented system-level
products. However, for most ordinary programming tasks, metaclasses are
not required.
For those who are interested, the architecture of the metaclass system
will be briefly discussed.
Warning!
This subject can be quite confusing, even to experts, and the description
given here is far from being comprehensive. Again, it is not necessary to
understand the metaclass architecture to use Class(y) v2.4.
Any simple class is created as an instance of the Class class. Instances
of the Class class contain variables such as name, superClass, and
messages. The contents of these variables describe a particular class.
Sending the class message to an object will return the class object
for that class. Examining these objects in the debugger can be
instructive.
If a class has class variables, then its class object must contain those
variables. For example, if a Window class contains a class variable called
activeList, the variable is stored in Window's class object, not in
its instances. The class object also contains the variables mentioned
above, such as name and superClass.
Such a class object - one containing an additional variable such as
activeList - is obviously not just an instance of the Class class. It
must have a class of its own, which we call a metaclass, because it is the
class of a class.
A metaclass, like any other class, is an instance of the Class class. But
what sets it apart from ordinary classes is that its superClass field
refers to the Class class, or to another metaclass. In other words, all
metaclasses ultimately inherit from the Class class. This ensures that
instances of a metaclass have the same basic structure as described by the
Class class, in addition to any other variables or methods which they may
define.
In the Window example, the Window metaclass would contain just a few
entries in its messages array, including an entry defining the
activeList variable. Instances of the Window metaclass will therefore
contain such a variable, in addition to the variables which they inherit
from their superclass, which as mentioned above, is Class.
The diagram below illustrates this. The boxes are somewhat similar to the
display provided by the debugger when looking at a class object. The
predefined Object class is shown, since all classes ultimately inherit
from it. The Class class is shown, since all classes are instances of it
or one of its subclasses. A Rectangle class is shown as a direct instance
of the Class class. The Rectangle class has no class variables of its own,
so it can be a direct instance of Class.
The Window class inherits from the Rectangle class. Since Window has a
class variable of its own, activeList, it needs a metaclass to
describe its structure. The Window metaclass is shown inheriting from the
Class class. The Window class is an instance of the Window metaclass.
Since the class described by the Window metaclass is a subclass of Class
because the superclass field refers to Class - the Window class inherits
all of the methods and instance variables defined in Class, as well as the
variable activeList, defined in the Window metaclass.
Each box below is a Class(y) object. The boxes also happen to be class
objects, since they are all instances of the Class class or one of its
subclasses (even the Class class object is an instance of the Class class,
an interesting and necessary circular relationship).
In the diagram below, the header of each box specifies the class
represented by that box. In each box's left-hand column, the names of the
class object's variables are listed. In the right hand column,
corresponding to each variable, is the value of that variable. Overall, it
is somewhat similar to the kind of display you see in the debugger.
The heavy arrows point from a subclass to its superclass. The light arrows
point from an object to its class, ie. to the class it is an instance of.
Class/Metaclass Relationships
+------------------------------+
| Object class |
|------------------------------|
| name | "Object" |
| superClass | NIL |
| vars | {} |
| methods | { "NEW", |
| | "CLASSH", |
| | "CLASS", |
| | "CLASSNAME" } |<--------------------------+
+------------------------------+ |
| . |superclass
instance of| | |
| |subclass of |
. | |
+------------------------------+ +--------------------------+
| Class class | | Rectangle class |
|------------------------------| instance of |--------------------------|
| name | "Class" |<-------------| name | "Rectangle" |
| superClass | Object | | superClass | Object |
| vars | { "NAME", | | vars | { "TOP", |
| | "SUPERCLASS", |-------+ | | "LEFT", |
| | "VARS" | inst | | | "BOTTOM", |
| | "METHODS" } | | | | "RIGHT" } |
| methods | { "NEW", ... } |<------+ | methods | { "NEW", |
+------------------------------+ | | "DRAW" } |
. . +--------------------------+
| | .
instance of| |subclass of |
| | |subclass of
| | |
+---------------------------------+ +--------------------------+
| Window class class (metaclass) | | Window class |
|---------------------------------| instance |--------------------------|
| name | "Window class" |<----------| name | "Window" |
| superClass | Class | of | superClass | Rectangle |
| vars | { "ACTIVELIST" } | | vars | { "BUF" } |
| methods | {} | | methods | { "NEW", |
+---------------------------------+ | | "OPEN", |
| | "CLOSE" } |
| activeList | NIL |
+--------------------------+
To complete the picture, sample individual instances of the Rectangle and
Window classes are shown below.
Sample Instances
+--------------------+ +-----------------+
| Rectangle instance | | Window instance |
|--------------------| |-----------------|
| top | 5 | | top | 7 |
| left | 5 | | left | 4 |
| bottom | 10 | | bottom | 18 |
| right | 34 | | right | 25 |
+--------------------+ | buf | "...." |
+-----------------+
Point of Interest
The arrows in the first diagram indicate that Object is an instance of
Class, even though Class is a subclass of Object. This important 'chicken-
and-egg' relationship is set up by Class(y) on initialization. Another
aspect of this relationship is the instance arrow which points from the
Class class back to itself. The Class class object is itself an instance
of the Class class.
This page created by ng2html v1.05, the Norton guide to HTML conversion utility.
Written by Dave Pearson