Encapsulation and Inheritance in Object-Orlented Programming Languages
Encapsulation and Inheritance in Object-Orlented Programming Languages
in
Object-Orlented Programming Languages
Alan Snyder
Software Technology Laboratory
Hewlett-Packard Laboratories
P.O. Box 10490
Pain Alto CA 94303-0971
(415) 857-8764
permission to copy without fee all or pan of this material is granted provided
that the copies are not made or distributed for direct commercial edvantage,
the ACM copyright notice and the title of the publication and its date appear,
amt notice is given that copying is by permission of the Association for
Computing Machinery. To copy otherwise, or to republish, requires a fee and/
or specific permission.
Our position is that being able to use inheritance without Many object-oriented languages relate subtyping and in-
making a public commitment to it in the external inter- heritance. For example, in Trellls/Owl, Simula, and C*÷
face of a class is valuable, and we will analyze how exist- a class x is a subtype of a class y if and only if x is a de-
ing object-oriented languages support this option. We will scendant of y. If the designer should reimplement class x
begin by considering only the single inheritance case, i.e., so that it inherits from class z instead of ¥, client programs
where the inheriting class (the child) directly inherits from that assume x is a subtype of y would no longer be legal,
a single class (the parent). Multiple inheritance introduces e v e n if the intended external interface of x {the operations)
additional problems and will be discussed below. is unchanged. Thus, the use of inheritance is exposed via
the subtyping rules. °
To avoid this problem, Subtyping should not be tied to in-
Excluding Operations heritance. Instead, subtyping should be based on the be-
Most object-oriented languages promote inheritance as a havior of objects. If instances of class x meet the external
technique for specialization and do not permit a class to interface of class y, then x should be a subtype of y. The
=exclude ~ an inherited operation from its own external in- example above demonstrates that the implementation hi-
terface. However, if inheritance is viewed as an implemen- erarchy need not be the same as the type hierarchy (as
tation technique, then excluding operations is both reason- defined by object behavior) !Canning85]. In tha~ example,
able and useful. stack inherits from deque but is not a subtype of deque,
For example, consider the abstractions stack and deque, and deque is a subtype of stack but does not inherit from
where a stack is a queue that permits elements to be added stack.
or removed from one end, and a deque is a queue that per- Behavioral subtyping cannot be deduced without formal
mits elements to be added or removed from either end. The semantic specifications of behavior. Lacking such specifi-
external interface of a deque is a superset of the external cations, one can deduce subtyping based solely on syntac-
interface of a stack: a deque has two additional operations tic external interfaces (i.e., the names of the operations)
for adding and removing elements from the "back end". [Cardelli84]. Alternatively (or in addition), one can allow
The simplest way to implement these two abstractions (at the designer of a class to specify which other classes it is a
least for prototyping purposes) is to define the class stack subtype of. The default may be that a class is a subtype of
to inherit from the class deque, and exclude the extra op- each of its parents. However, as demonstrated by the ex-
erations. Stack inherits the implementation of deque, but ample, the designer must be able to specify that the class is
is not a specialization of deque, as it does not provide all not a subtype of a parent or that the class is a subtype of an
the deque operations. unrelated cla~s (not its parent). The first case arises when
\/ X
x will now have the effect of invoking the operation o on
class s twice, on the same set of instance variables. If o on z
has side-effects, the result might not be acceptable. Thus,
in this example, a change to the use of inheritance by a
F i g u r e 2: A l t e r i n g t h e i n h e r i t a n c e s t r u c t u r e . class (y2) has broken one of its clients (x), even though
its operations have the same external behavior; the use of
more parents, but only if the operations are actually differ- inheritance is therefore (implicitly) part of the external in-
ent. In other words, if the same operation (from the same terface of the class y2.
class) is inherited by a class via different paths through the
inheritance graph, it is not an error.
Linear Solutions
This same-operation exception is motivated by convenience,
The second strategy for dealing with multiple inheritance
as operation conflicts are inevitable when there is merging
is to first flatten the inheritance graph to a linear chain,
in the inheritance graph. Although this exception may at
without duplicates, and then treat the result as single in-
first glance seem innocuous, it forces the use of inheritance
heritance. This strategy is used by Flavors (as recently
to be part of the external interface.
revised) IMoon86] and CommonLoops [Bobrow86 I. These
Consider further the example shown in Figure I. If an op- languages use similar algorithms for creating a total order-
eration o is defined (only) by the class z, it will be inherited ing that preserves the ordering along each path through the
by yl and y2 and then by x (with no error). Now suppose inheritance graph (a class never appears after one of its an-
the class y2 is relmplemented so that it no longer inherits cestors). Flavors attempts as well to preserve the relative
from s (see Figure 2) but still supports the same behavior. ordering of the parents of a class (the first parent of a class
Class x will now be in error, because it is inheriting two dif- never appears after the second, etc.); an error is signalled
t'ezent operations named o, one from class z via class yl and if no total ordering exists that satisfies all such constraints.
one from class y2. (The operations are different yet have
While the relative ordering of a class and its ancestors is
equivalent behavior on objects of their respective classes.)
preserved in the total ordering, unrelated classes can be
Thus, the change to class y2 to stop inheriting from z was
visible to class x, a client of class y2. The external inter-
face of y2 was therefore changed, even though the external Z