Prototypes and Object Orientation
Two terms are quite often confused when describing programming languages: class-based and object-oriented:
- Simula was the first class-based language. It provided classes (actually implemented using closures) as a means of encapsulating abstract data types.
- Smalltalk was the first object-oriented language. It provided a mechanism for decomposing programs into subprograms that ran on a simplified model of a computer and communicated with each other via message-passing.
Classes and Delegates
A very common pattern in object-oriented languages is the idea of delegation. An object uses another to provide some of its functionality. This pattern is especially common in user interfaces, as a mechanism for combining the generic behavior of a view with some specific behavior for the program.
In class-based languages, subclassing is a special case of delegation. Each class has some number of superclasses to which it delegates. When you request some functionality from a class, it either implements that functionality itself, or it delegates the functionality t to a superclass. This design is extended further by objects, which are instances of classes, and therefore delegate most of their operations to a class. In a language like Smalltalk or Java, instances just contain datathey use their class delegate to provide all method implementations.
This level of delegation creates the only really confusing thing in the Smalltalk system: the metaclass. In Smalltalk, everything is an object, including classes. Objects are instances of classes; therefore, classes are instances of metaclasses. For consistency, the metaclasses must be instances of metametaclasses, which should be instances of metametametaclasses, and so on. To avoid this infinite recursion, metaclasses are actually also instances of classes. This same model exists in Objective-C, by the way, but is only exposed when you interact with the runtime library directly.
The existence of both kinds of delegation makes the delegation chain quite complex. Every message is delegated to the object's class and then delegated up the superclass chain. Messages are never delegated along the metaclass chain, except for the initial delegation.