[comp.object] Inheriting parts of superclasses

craig@Neon.Stanford.EDU (Craig D. Chambers) (11/18/90)

In article <1990Nov16.065609.15460@tukki.jyu.fi> sakkinen@jytko.jyu.fi (Markku Sakkinen) writes:
>In article <11113@pt.cs.cmu.edu> ddean@rain.andrew.cmu.edu (Drew Dean) writes:
>>        if a subclass only inherits parts of its superclass
>>(ie. some subset of the methods and/or variables), how can an instance
>>of the subclass be used anywhere an instance of the superclass can be used ?
>>In my (comparably primitive) understanding of OOP, this is important.  Without
>>this property, what good are abstract classes, which seem to be a useful 
>>organizational tool ?
>
>Such partial inheritance can only be used for inheriting implementation
>(what I called "incidental inheritance" in my ECOOP'89 paper),
>thus more typically with concrete than abstract superclasses.
>An instance of the subclass can _not_ be substituted for an instance
>of the superclass.
>
>In my opinion, inheriting only parts of superclass, say C,
>into a subclass, say D, is a highly dubious idea even for this purpose.

If these comments are in response to my earlier posting, then I
believe I have been misunderstood.  I'm not suggesting that
programmers combine random pieces of source code to form new classes,
constantly patching code with partial inheritance to fix bugs or add
functionality.  Nooooo.  Nor am I talking about systems where source
code is unavailable and so class hierarchies must be bent out of
shape.  While this may be a problem for commercial software
frameworks, source code is always available in my ivory tower.

When I talk about inheriting parts of classes, I am referring to the
different aspects or facets (I don't have a better word yet) of
classes.  These aspects were listed in my previous posting, but since
people didn't seem to read them there, I'll (briefly) repeat:

Aspect 1:  Source code of methods
Aspect 2:  Format of instances (instance variables/instance template)
Aspect 3:  Specification of type/interface

Most existing class-based languages combine 1 and 2; some combine 3 as
well.  An classless language uses separate objects for 1 and 2, thus
allowing more reuse of code (i.e. inheriting 1) without being forced
to inherit representation as well (i.e. overriding 2).  As long as a
subclass inherits 3 (either explicitly in a statically-typed language
with proper subtyping rules or conceptually in a dynamically-typed
language), instances of the subclass may be substituted for instances
of the superclass, even if 1 and/or 2 are not inherited.

Note that to inherit 1 but not 2, a subclass must provide an alternate
implementation for any instance variables accessed by methods
inherited from the superclass and not overridden. These alternate
implementations may be methods instead of variables.  The language
must access instance variables using messages instead of hard-coded
memory loads; Trellis/Owl and Self are languages that do access all
variables using messages.  Trellis/Owl doesn't explicitly provide for
inheriting behavior without representation, but does allow
representation to be overridden with behavior, which is just as good.

Of course, through disciplined programming conventions you can
separate 1 and 2 by using different classes for each.  Fairly common
wisdom that achieves this is to only inherit from abstract classes,
not concrete classes, and only declare instance variables in concrete
classes.  Abstract classes must access instance variables using
messages.  Intermediate positions are also possible that only follow
this rule when necessary (assuming all source code is available to
support future reorganization when necessary).

But these conventions are awkward and sacrifice the ability to inherit
Aspect 2.  Why not just get the inheritance mechanism right in the
first place?  Or why not just move to a classless language, since they
are more flexible and probably more powerful than class-based
languages?  In the convention above for programming in a non-ideal
class-based language, abstract classes are a lot like traits objects
in classless languages, and concrete classes are a lot like prototype
objects, but prototype objects can inherit Aspect 2 from other
prototype objects using the normal object inheritance rules.

-- Craig Chambers