5 Types and Classes
initialize
and make
, using initialization information supplied by the class definition and by keyword arguments in the call to make
. Much of this behavior is supplied by the default make
method defined on <class>
.
make
method may be shadowed by a user-supplied method specialized with a singleton specializer. This enables the user method to get at all the arguments to make
, and to provide actual instantiation and initializations based on them. For example, a singleton method on an abstract class can reinvoke make
on a concrete subclass of the abstract class, passing along the same or augmented initialization arguments.
make
method examines its keyword arguments, which are known as the supplied initialization arguments. It then produces a set of defaulted initialization arguments by augmenting the supplied initialization arguments with any additional initialization arguments for which default values are defined by the class or any of its superclasses.make
will use the leftmost occurance. This is consistent with keyword argument conventions used in function calls.
make
method signals an error if any required init-keyword is absent from the defaulted initialization arguments, or if any of the defaulted initialization arguments are not valid for initialization of that class. An initialization argument is valid if it is specified as an init-keyword in a slot specification or initialization argument specification, or if it is permitted by one or more of the initialize
methods applicable to an instance of the class.
make
method allocates an instance and initializes all the slots for which it can provide values, as follows
<type-error>
is signaled if the value is not of the type declared for the slot.
make
method then calls initialize
on the initialized instance and the defaulted initialization arguments. Methods on initialize can access these arguments by accepting them as keyword parameters or in a rest parameter. If they are accepted in a rest parameter and the defaulted initialization arguments contained duplicate keywords, it is undefined whether any entries other than the leftmost for that keyword will be present.
initialize
method typically calls next-method
, and then performs its own initializations. (Note that it won't have to initialize slots that were initialized by the default method on make
.)
make
method ignores the value of the call to initialize
and returns the instance.
The values of virtual slots are not automatically initialized when a new instance is created. The programmer must perform any necessary initialization. This would usually be done inside a method on initialize
. Because the values of virtual slots are often computed from other values at run-time, many virtual slots will not require any explicit initialization.
make
is guaranteed to be a general instance of the first argument to make
, but not necessarily a direct instance. This liberality allows make
to be called on an abstract class; it can instantiate and return a direct instance of one of the concrete subclasses of the abstract class.
define abstract class <dog> (<object>) end class define class <yorkshire-terrier> (<dog>) end class define method make (the-class == <dog>, #rest init-args, #key) apply(make, <yorkshire-terrier>, init-args) endmake(<dog>)
make
is not required to return a newly allocated instance. It may return a previously created instance if that is appropriate. If a new instance is allocated, make will call initialize on the instance before returning it.
The make
method on <class>
returns a newly allocated direct instance of its first argument.
Programmers may customize make
for particular classes by defining methods specialized on singletons of classes. These methods may reinvoke make
on a subtype of the class, or they may obtain the default make
behavior by calling next-method.
The default make
method signals an error if its first argument is an abstract class. An instantiable abstract class must override this method with its own method for make
.
make
whenever an instance is created, as follows:
make
and the slot has not yet been initialized, then the slot is initialized from the init specification. If the slot has already been initialized, no action is taken.
make
, then the slot is set to the value of that initialization argument, regardless of whether the slot was previously initialized.
slot-initialized?
function, described on page 246. There is no portable mechanism for resetting a slot to the uninitialized state once it has been initialized.To support the slot-initialized? protocol in a virtual slot, programmers must define a method for slot-initialized? that specializes on the getter of the slot and the class.
Inherited slot specifications identify the slot to be modified by the getter name. The inherited slot specification is only allowed if the class does indeed inherit a slot with that getter.
(An inherited slot specification is not required to include an init specification. If it does not, its only purpose is to ensure that the slot is present in a superclass. Because init specifications are not allowed for virtual slots, this is the only valid form of inherited slot specification for virtual slots.)
If an inherited slot specification supplies an init specification, it overrides any init specification inherited from a superclass. This allows the init specification of an inherited slot to be replaced in a subclass, thereby changing the default initial value of the slot.
define class <animal> (<object>) slot n-legs, init-value: 4; end class; define class <spider> (<animal>) inherited slot n-legs, init-value: 8; end class;
define class
forms, and have a syntax similar to that of slot specifications.Initialization argument specifications allow the type of an initialization argument to be restricted, they allow an initialization argument to be declared to be required, and they allow the specification of a default value for an initialization argument.
Note that an initialization argument will only be used if it is specified to be the init-keyword of a slot, or if it is used as a keyword argument in an applicable method on initialize
. An initialization argument specification can supply a default value for an initialization argument, and it can restrict the type of the argument or make it required, but it does not by itself cause the argument to be used when initializing an instance.
There are two kinds of initialization argument specifications: required initialization argument specifications, and optional initialization argument specifications.
A required initialization argument specification asserts that the initialization argument must be present in the defaulted initialization arguments. The default make
method will signal an error if no such initialization argument is present.
An optional initialization argument specification can be used to specify a default value for the initialization argument, using an init specification. When a call to make
does not specify the initialization argument, the default make
method will add it to the defaulted initialization arguments with the value of the init specification.
The type argument has the same meaning in both kinds of initialization argument specification: it restricts the type of that initialization argument. Note that this is not the same thing as restricting the type of the slot.
The following example shows how initialization argument specifications can be used to override the behavior of a superclass:
define class <person> (<object>) slot favorite-beverage, init-value: #"milk", init-keyword: favorite-beverage:; slot name required-init-keyword: name:; end class <person>; define class <astronaut> (<person>) keyword favorite-beverage: init-value: #"tang"; keyword name: init-value: "Bud"; end class <astronaut>;In this example, thet
<astronaut>
class provides default values for the favorite-beverage:
and name:
init-keywords. In addition to indirectly supplying default values for these slots, this also has the effect of making the name:
argument optional in calls to make
on <astronaut>
. If the call to make
does not specify a name:
, the name:
will be added to the defaulted initialization arguments by the default make
method before the defaulted initialization arguments are checked for completeness.More than one keyword initializable slot may be initialized from the same initialization argument (that is, more than one keyword initializable slot may specify the same init-keyword). However, an error is signaled if a single define-class form has more than one initialization argument specification for the same keyword. An error will also be signaled if a single define-class form has a keyword initializable slot which includes an init specification and also includes an initialization argument specification for the same keyword that is either required or provides a default value. These error situations are all indications of code that can never be reached.
required-init-keyword:
is treated as if the initialization argument specification required keyword
K had been specified in the class definition.
<object>
.
Generated with Harlequin WebMaker