Книга: Practical Common Lisp
The bulk of a
DEFCLASS form consists of the list of slot specifiers. Each slot specifier defines a slot that will be part of each instance of the class. Each slot in an instance is a place that can hold a value, which can be accessed using the
SLOT-VALUE takes an object and the name of a slot as arguments and returns the value of the named slot in the given object. It can be used with
SETF to set the value of a slot in an object.
A class also inherits slot specifiers from its superclasses, so the set of slots actually present in any object is the union of all the slots specified in a class's
DEFCLASS form and those specified in all its superclasses.
At the minimum, a slot specifier names the slot, in which case the slot specifier can be just a name. For instance, you could define a
bank-account class with two slots,
balance, like this:
(defclass bank-account ()
Each instance of this class will contain two slots, one to hold the name of the customer the account belongs to and another to hold the current balance. With this definition, you can create new
bank-account objects using
(make-instance 'bank-account) ==> #<BANK-ACCOUNT @ #x724b93ba>
The argument to
MAKE-INSTANCE is the name of the class to instantiate, and the value returned is the new object. The printed representation of an object is determined by the generic function
PRINT-OBJECT. In this case, the applicable method will be one provided by the implementation, specialized on
STANDARD-OBJECT. Since not every object can be printed so that it can be read back, the
STANDARD-OBJECT print method uses the
#<> syntax, which will cause the reader to signal an error if it tries to read it. The rest of the representation is implementation-defined but will typically be something like the output just shown, including the name of the class and some distinguishing value such as the address of the object in memory. In Chapter 23 you'll see an example of how to define a method on
PRINT-OBJECT to make objects of a certain class be printed in a more informative form.
Using the definition of
bank-account just given, new objects will be created with their slots unbound. Any attempt to get the value of an unbound slot signals an error, so you must set a slot before you can read it.
(defparameter *account* (make-instance 'bank-account)) ==> *ACCOUNT*
(setf (slot-value *account* 'customer-name) "John Doe") ==> "John Doe"
(setf (slot-value *account* 'balance) 1000) ==> 1000
Now you can access the value of the slots.
(slot-value *account* 'customer-name) ==> "John Doe"
(slot-value *account* 'balance) ==> 1000