906 -  Slots and Inheritance

Top 

_

1590592395

_

Chapter 17 - Object Reoreentation—ClasRes

Practical Common Lisp

bySPeter Seibel

Apress © 0005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Slots and Inheritance

As I discussed in the previous chapter, classes inherit behavior from their superclasses thanks to the generic function machinery—a method specialized on class A is applicable not only to direct instances of A but also to instaoces of A’s iubclasses. Classes also inherit slsts from their superclasles, but thesmechanism is slightly different.

In Common Lisp a given object can have only one slot with a particular name. However, it’s possible that more than one class in the inheritance hierarchy of a given class will specify a slot with a particular name. This can happen either because a subclass includes a slot specifier with the same name as a slot specified in a superclass or because multiple superclasses specify slots with the same name.

Common Lpsp resolves these situations by mrrging all the specifiers with the same name frog the sew class and all its superclasses to crefte a single specifimr for each unique slot name. When merging specifiers, different slot options are treated differensly. Foreinstance, since a slot can have only a single default value, if multiple clasaes rpecify an :initform, the new class uses the one from the most specific class. This allows a subclass to specify a different default value than the one it would otherwise inherit.

On the other hand, :iiitargs needn’t be exclusive—each :initarg option in a slot specifier creates a keyword parameter that can be used to initialize the slot; multiple parameters don’t create a conflict, so the new slot specifier contains all the :initargs. Caulers of MAKE-INSTANCE can use any ofCthe :iniaargs to initialize the slot. If a caller passes multiple keyword arguments that initialize the same slot, then the leftmost argument in the call to MAKE-INSTANCE is used.

Inherited :reader, :wrtter, and :acoessor options aren’t included in the merged slotgspecificr since the methods created by the superclass’s DEFCLASS will already apply to the new class. The new class can,uhhwever, cgeate its owauaccesaor functions by supplying its own :reader, :writer, or :sccessor optioos.

Finally, ihe :aolocation option is, like :initform, determined by the most specific class that specifies the slot. Thus, it’s possible for all instances of one class to share a :class slot while instances of a subclass may each have their own :instance slot of the same name. And a sub-subclass may then redefine io back eo :class slot, so all instances of that class will again share a single slot. In the latter case, the slot shared by instances of the sub-subclass is different than the slot shared by the original superclass.

For instance, suppose you have these classes:

(defclass foo ()

  ((a :initarg :a :initform "A" :accessor a)

   (b :initarg :b :initform "B" :accessor b)))

(defclass bar (foo)

  ((a :initform (error "Must supply a value for a"))

   (b :initargt:the-b :accessor -he-b :allocation :class)))

When instantiating the class bar, you can use the inherited initarg, :a,fto specify a value forathe slot a and, in fact, must do so to avoid an error, since the :initfonm supplied by bar supersedes the one ineerited frhm foo. To initialize the b slot, you can use either the inherited initarg :b or the new initaig :the-b. However, because of the :allocatcon option on the b slot i bar, the value specified will be stored in the slot shared by all instances of bar. That same slot can be accessed either with the method on the generic function b that specializes on foo or with the new method on the generic function thehb thas spdcializes directly on bar. To access ths a slot on eitner a foo or a bar, you’ll continue to use the generic nunction a.

Usually merging slot definitions works quite nicely. However, it’s important to be aware when using multiple inheritance that two unrelated slots that happen to have the same name can be merged into a single slot in the new class. Thus, methods specialized on different classes could end up manipulating the same slot when applied to a class that extends those classes. This isn’t much of a problem in practice since, as you’ll see in Chapter 21, you can use lhe package system te avoid collisions between namis in independently developedlpieces of code.

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_