Previous | Table of Contents | Next |
In object-oriented programming, the code is organized around classes, which represent abstractions of encapsulated data useful in the domain being modeled in the application. At runtime, specific data objects, or instances, of these classes are created, initialized, and operated on. In CLOS, classes must be defined before instances can be used or created. This is not always true; other object semantics include taking an existing object as a template and building new objects by customizing the already existing object (sometimes known as a prototype-based system). A class definition defines the instance structure, that is, a set of named data types, known as the named slots. Named slots are known as instance variables in Smalltalk or as member data elements in C++. Instances are known as objects of a class in C++.
Class definitions also may contain other information, including inheritance, and a great deal of information about each slot (or slot options), including the type of data the slot uses, initialization functions, and names of accessor functions. For example, here are CLOS definitions of a class named point:
(defclass point () ((x :initarg :x :initform 0.0 :accessor x-coordinate :type single-float) (y :initarg :y :initform 0.0 :accessor y-coordinate :type single-float)))
The class definition defines that instances of type point have two slots, one named x and the other named y. Each slot is defined as a list starting with the name of the slot and followed by a set of slot options, defined by keywords (symbols beginning with a colon). For example, the slot named x has four options named by the keywords :initarg, :initform, :accessor, and :type. The first two options are used to specify both an initialization value to the slot at creation time and a default initialization value (in this case, 0.0) if no initial value is specified. :accessor names the operation (called a generic function in CLOS) x-coordinate, which is used to look up or set the value in the x slot.
The form
(make-instance point :x 1.0 :y 1.0)
creates and initializes an instance of type point with its x slot and its y slot both set to 1.0.
Note that the x and y slots of point have a type specified (i.e., single-float). CLOS may use type information, if present, but unlike C++, where type information is mandatory, type information is not enforced and in some implementations may be ignored. C++ automatically defines a constructor for objects using the new operator. As in CLOS, C++ has mechanisms for providing initial values as arguments and for default values. For example, in C++, the equivalent class definition might look like
class Point { public: Point( float x, float y); private: float _x = 0.0; float _y = 0.0; :}
and the constructor is
Point::Point(float x, float y) { _x = x; _y = y; }
and initialization would look like
new Point(1.0, 1.0);
Smalltalk has a slightly different paradigm: As in C++, instances are created by sending the new message to the name of the class, but initial values are always specified. In Smalltalk, you would end up using a creation message as in
Point x: 0.0 y: 0.0
because default initialization is not specified in Smalltalk class definitions.
By default, CLOS also permits two kinds of slots: local slots and shared slots. The value in a local slot is unique to each instance, but the value in a shared slot is seen by all instances of the class. I defer discussing shared slots to section 5.4.1.
Previous | Table of Contents | Next |