[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

draft on inheritance of slots and defclass options



Most of the following came from Danny's message of awhile back.   We
changed the inheritance behavior of :type so that the compiler could
do some optimization based on the :type option given in a local DEFCLASS
description.  

This draft seems long for the subject matter it's covering, but I think 
it's worth spelling out all the possibilities.   As soon as people read
this and give comments about it, I'll edit it into the document.  


------------------------------------------------

INHERITANCE 

A class inherits methods, slots, and some DEFCLASS options from all of
its superclasses.  However, the class can choose to override an 
inherited method, slot, or DEFCLASS option.  This section describes what
is inherited from superclasses, and how a class can override an aspect
of inherited behavior.  

INHERITANCE OF METHODS

Methods are inherited by subclasses.   That is, a method provided by a 
class is applicable for use on instances of any subclass of that 
class.   In some cases, an inherited method can be shadowed by providing
a method for a more specific class.   When standard method combination
is used, the primary method can be shadowed by a method on a more
specific class.   (However, if the more specific method uses 
CALL-NEXT-METHOD, the next most specific primary method is called.)  

The inheritance of methods acts the same way regardless of whether the 
method was created using DEFMETHOD or by using one of the DEFCLASS 
options that cause methods to be generated automatically (for reading or 
accessing the value of a slot). 

INHERITANCE OF SLOTS 

In general, slots are inherited by subclasses.  An instance has at most
one slot by any given name accessible to it.  The inheritance of slots
depends on whether the inherited slot is allocated by :class or
:instance, and whether the :allocation slot option is given in the local
slot-description.   There are several different cases.  

1.  In the simplest case, a class does not provide a local description
of a slot with the same name as a slot provided by its superclass.  If 
it is an :instance slot, the subclass allocates storage for it in each
instance.  If it is a :class slot, the allocation of the slot is done by 
the superclass, and that single slot is accessible by instances of both 
the superclass and the subclass.  

2.  Whenever a class specifies :allocation :class, a new :class slot is
created, and any slot with that name provided by a superclass is not
accessible to instances of this class.

3.  Whenever a class specifies :allocation :none for a slot, no slot
with that name is accessible to instances of this class.  Thus, the
:allocation :none option allows for subtractive inheritance; a class can
specify :allocation :none to prevent access to a slot supplied by a 
superclass.

4.  Whenever a class provides a local description of an :instance slot,
and its superclass provides a description of a :class slot with  
the same name, only the :instance slot that was described locally
is accessible to the subclass.   Only the :class slot is accessible  
instances of the superclass.   (Note that the DEFCLASS default :allocation
is :instance, so a slot description is treated as an :instance slot 
if the :allocation option is not explicitly supplied.)

5.  Whenever a class provides a local description of an :instance slot,
and its superclass also provided a description of an :instance slot with
the same name, the effect of the local slot description is to override
or alter some of the inherited characteristics of the slot, such as its
:initform or :type options.  (The inheritance behavior of each DEFCLASS
option is described further on in this section.)

The wording of the above cases mentions one subclass and one superclass,
but a class often has more than one superclass.   The class precedence
order is used to determine how the slots are inherited.  When a class is
defined, the slots that it will be able to access are determined by
considering each local slot-description, and the description of each
slot that is given by the most specific superclass in the class
precedence list.   The examples further on in this section should
clarify this behavior.

INHERITANCE OF DEFCLASS OPTIONS

:ACCESSOR -- This option is not inherited; subclasses do not
automatically generate methods for accessing a slot unless the :ACCESSOR
prefix is specified in the local description.   However, a subclass does
inherit the methods generated by this option, in the sense that the
methods are applicable for instances of the subclass.   Because these 
methods are primary methods, when standard method combination is used  
the subclass can shadow the inherited methods by providing more specific
methods, either by using the :ACCESSOR option or using DEFMETHOD.   The
type of inheritance described here also applies to the methods generated
by the :reader, :accessor-prefix, and :reader-prefix options.

:READER -- This slot option is not inherited; see the description of the
:accessor slot-option.

:ALLOCATION -- This option is not inherited by subclasses.  However, if
a local slot description is given for a slot with the same name as a
slot provided by a superclass, this option affects the inheritance of
the slot.  The semantics of slot inheritance and the :allocation option
are described above.

:INITFORM -- The :initform option is inherited, and can be overridden in
a straightforward way.  In the case of an inherited :instance slot, if
the :initform option is given in a local description, the local
:initform completely overrides the inherited :initform.

:TYPE -- The :TYPE option is inherited as follows.   When a class is
being defined, the slot descriptions of all of its superclasses
(including itself) are considered, regardless of the allocation of the
slot. The type of the value of the slot is constrained to satisfy all of
the type constraints given in the descriptions of each of its
superclasses, including itself.  That is, if T1, T2 and so on are the
type constraints given by the class and all of its superclasses, the
value of the slot must satisfy (typep value '(and T1 T2 T3...).  [This 
inheritance behavior allows a compiler to optimize on the basis of the
:TYPE option in the DEFCLASS form.   Some operations can be improved,
when the slot directly is involved in an arithmetic expression, such as
being able to emit the machine addition instruction with only overflow
checking.]

CLASS OPTIONS:

:ACCESSOR-PREFIX -- This slot option is not inherited; see the
description of the :ACCESSOR slot-option. 

:READER-PREFIX -- This slot option is not inherited; see the description
of the :ACCESSOR slot-option.

:CONSTRUCTOR -- This option has no effect on subclasses; it is not
inherited.   

:DOCUMENTATION -- This option has no effect on subclasses; it is not
inherited.  

:METACLASS -- This option has no effect on subclasses; it is not
inherited.


EXAMPLES OF INHERITANCE: 

(defclass C1 () ((S1 :initform 5.4 :type number) 
                 (S2 :allocation :class))

(defclass C2 (C1) ((S1 :initform 5 :type integer)
                   (S2 :allocation :instance)
                   (S3 :accessor C2-S3))
  :reader-prefix C2-) 

(defclass C3 (C2) ((S2 :allocation :none))) 

(defclass C4 (C3 C2) ()) 

C1 has an :instance slot named S1, whose default initial value is 5.4, 
and whose value is constrained to be a number.   C1 also has a :class 
slot named S2.

C2 has access to an :instance slot named S1, whose default initial value 
is 5, and whose value is constrained to satisfy (typep value '(AND 
integer number)).  C2 has access to two :instance slots, named S1 and
S2.  C2 has methods defined for reading the value  
of its slots; these methods are for the generic functions named:  C2-S1,
C2-S2, and C2-S3.  There is also a SETF method for use with C2-S3.

C3 has access to an :instance slot named S1, whose default initial value
is 5, and whose value is constrained to satisfy (typep value '(AND
integer number)).  C3 also has access to a slot named S3.  C3 has  
methods applicable for reading the value of the slots S1, S2, and S3.  
Note that although C3 has a method for reading the value of slot S2, it 
does not have access to that slot, so using the method would result in 
an error.  

The class precedence order for C4 is:  (C4 C3 C2 C1).  Because C3 comes 
before C2 in the precedence order, class C4 does not have access to slot
S2.