[comp.lang.eiffel] Kinds of inheritance

sakkinen@tukki.jyu.fi (Markku Sakkinen) (09/04/89)

Andreas Guendel (guendel@exunido.uucp) has recently posted a couple
of very pertinent articles in this group.
Look them up; I will not directly quote them here.

In article <1301@cheops.eecs.unsw.oz> marku@cheops.eecs.unsw.oz (Mark Utting) writes:

>In my research work on verifying systems that use multiple inheritance
>I have found that it is semantically useful to distinguish between
>`SUBTYPE' inheritance (eg. CHILD1 is a subtype of PARENT) and `REUSE'
>inheritance (eg. CHILD2 shares PARENT's implementation or specification).
>
>Practically, the difference is that CHILD1 objects are intended to behave 
>like PARENT objects, whereas CHILD2 objects may behave *quite* differently.
>This means that the type system should not allow CHILD2 objects to be assigned
>to PARENT variables (because they are not *intended* to behave similarly).
>
>In the above example, it is my opinion that `fixed-stack' should inherit 
>from `array' via REUSE inheritance rather than SUBTYPE inheritance.

[The example is from Meyer's "OOSC": 10.4.1 "The marriage of convenience"
(p. 241). It is the very first example of multiple inheritance presented
in the book.]

I made a similar distinction as Utting in my paper "Disciplined Inheritance"
at ECOOP'89 (proceedings published by Cambridge University Press),
the terms used there are 'essential' and 'incidental' [inheritance].
I also presented some reasons why most OOPL's require programmers to use
"inheritance" even in the cases where the interfaces of the superclass
and the subclass have nothing in common. (In this respect, CLU, Ada
and Modula-2 are better off!)

So, why cannot a FIXED_STACK object simply have an ARRAY object as
a component, but FIXED_STACK must "inherit" ARRAY? Because in Eiffel
(and most other object-oriented languages) one cannot declare some
desirable restrictions otherwise:
1. Each FIXED_STACK object must have a _permanent_ ARRAY part.
2. ARRAY parts must not be shared or otherwise visible outside
   the FIXED_STACK objects.
In those OOPL's that allow objects to be _directly contained_
within other objects (e.g. C++, EXTRA), these problems practically disappear
and programmers can avoid abusing "inheritance".
On the other hand, in weakly typed languages like Smalltalk one cannot
even specify the class of any component (instance variable) of an object,
so there a still greater need to apply "incidental" or "reuse" inheritance.

I would like to point out that these problems are not caused specifically
by _multiple_ inheritance. Nevertheless, if you have multiple inheritance,
you can use inheritance more liberally. Repeated inheritance, a specialty
of Eiffel, must logically always be "incidental", as argued in my paper.

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland

mjl@cs.rit.edu (09/12/89)

This is actually a followup to both Mark Utting and Markku Sakkinen.

In article <1301@cheops.eecs.unsw.oz> Mark Utting writes:
>Practically, the difference is that CHILD1 objects are intended to behave 
>like PARENT objects, whereas CHILD2 objects may behave *quite* differently.
>This means that the type system should not allow CHILD2 objects to be assigned
>to PARENT variables (because they are not *intended* to behave similarly).

>In the above example, it is my opinion that `fixed-stack' should inherit 
>from `array' via REUSE inheritance rather than SUBTYPE inheritance.

This seems about right to me, but as Markku has noted, the fixed
stack could be a client of array, rather than an heir.  In general,
though, this can make it difficult to mirror the class semantics
cleanly, and REUSE inheritance would be nice.  Note that C++ 2.0 (flame
retardant:  I'm no great C++ fan) can handle REUSE via "private"
inheritance.  That is, if class C inherits from B "publicly", then all
C's are B's, and one can assign a C to a B.  If the inheritance is
"private", then C is just using B's functionality, and their types are
independent.

This seems to capture the two forms of inheritance, though the
terminology (public/private) is a bit baroque.  Given that multiple
inheritance is an integral part of the Eiffel development model, I'd
also like to see these two forms kept distinct.

In article <1268@tukki.jyu.fi> Markku Sakkinen writes:
>
>So, why cannot a FIXED_STACK object simply have an ARRAY object as
>a component, but FIXED_STACK must "inherit" ARRAY? Because in Eiffel
>(and most other object-oriented languages) one cannot declare some
>desirable restrictions otherwise:
>1. Each FIXED_STACK object must have a _permanent_ ARRAY part.
>2. ARRAY parts must not be shared or otherwise visible outside
>   the FIXED_STACK objects.

What am I missing here?  In Eiffel, you can certainly have an
unexported attribute that's an array, and if it's Created when the
fixed stack object is Created, it will be non-shared (unless you do
strange Cloning).  And why is such an array any less "permanent" than
one that is directly contained in the in each object:  from a client's
view, the stack storage comes into being when the object is Created,
and is lost when the object is Forgotten.

>I would like to point out that these problems are not caused specifically
>by _multiple_ inheritance. Nevertheless, if you have multiple inheritance,
>you can use inheritance more liberally. Repeated inheritance, a specialty
>of Eiffel, must logically always be "incidental", as argued in my paper.

You seem to be equating incidental inheritance with REUSE inheritance.
If so, why is the following not valid SUBTYPE inheritance?

Suppose I have a class VEHICLE, and subclasses of this called CAR and
TRUCK.  I may want to model a small van as both a CAR and a TRUCK,
kicking in repeated inheritance.  We get the following class
hierarchy:

	     VEHICLE
	        /\
	       /  \
	     CAR TRUCK
	       \  /
	        \/
	       VAN

I'd argue that a VAN is a subtype of CAR, TRUCK, and VEHICLE, exposing
different aspects of its nature under all these guises.

Mike Lutz
Rochester Institute of Technology
Mike Lutz	Rochester Institute of Technology, Rochester NY
UUCP:		{rutgers,cornell}!rochester!ritcv!mjl
CSNET:		mjl%rit@relay.cs.net
INTERNET:	mjl@cs.rit.edu

sakkinen@tukki.jyu.fi (Markku Sakkinen) (09/18/89)

In article <1283@cs.rit.edu> mjl@isc.rit.edu writes:
- [...]
-In article <1268@tukki.jyu.fi> Markku Sakkinen writes:
->
->So, why cannot a FIXED_STACK object simply have an ARRAY object as
->a component, but FIXED_STACK must "inherit" ARRAY? Because in Eiffel
->(and most other object-oriented languages) one cannot declare some
->desirable restrictions otherwise:
->1. Each FIXED_STACK object must have a _permanent_ ARRAY part.
->2. ARRAY parts must not be shared or otherwise visible outside
->   the FIXED_STACK objects.
-
-What am I missing here?  In Eiffel, you can certainly have an
-unexported attribute that's an array, and if it's Created when the
-fixed stack object is Created, it will be non-shared (unless you do
-strange Cloning).  And why is such an array any less "permanent" than
-one that is directly contained in the in each object:  from a client's
-view, the stack storage comes into being when the object is Created,
-and is lost when the object is Forgotten.

I guess you are right concerning Eiffel (in contrast to many other OOPL's):
permanency can be ensured by using a "once" function to create the array.
Keeping the array completely invisible outside the fixed stack requires
a little discipline in defining and programming the public features,
but that is a small matter. - This actually makes me wonder even more
why Meyer wanted to apply multiple inheritance to this case!

->I would like to point out that these problems are not caused specifically
->by _multiple_ inheritance. Nevertheless, if you have multiple inheritance,
->you can use inheritance more liberally. Repeated inheritance, a specialty
->of Eiffel, must logically always be "incidental", as argued in my paper.
-
-You seem to be equating incidental inheritance with REUSE inheritance.
-If so, why is the following not valid SUBTYPE inheritance?
-
-Suppose I have a class VEHICLE, and subclasses of this called CAR and
-TRUCK.  I may want to model a small van as both a CAR and a TRUCK,
-kicking in repeated inheritance.  We get the following class
-hierarchy:
-
-	     VEHICLE
-	        /\
-	       /  \
-	     CAR TRUCK
-	       \  /
-	        \/
-	       VAN
-
-I'd argue that a VAN is a subtype of CAR, TRUCK, and VEHICLE, exposing
-different aspects of its nature under all these guises.

Sorry, I should have made myself clearer. I mainly meant _direct_ repeated
inheritance in the terminology of OOSC; but also _indirect_ repeated
inheritance if it causes a repetition on the _instance_ level.
(The indirect case may happen in any language that suports MI,
but I have not seen the direct case in any other language than Eiffel.)
In your example, a VAN instance is exactly one VEHICLE instance,
so this is true subtyping. - In my paper, I criticised the similar-looking
example from OOSC ("transcontinental drivers", p. 275-277),
because there a FRANCE_US_DRIVER instance contains "one and a half"
DRIVER instances.

-Mike Lutz
-Rochester Institute of Technology

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland