% Multiparadigm Programming with Python 3 \
  \
  Understanding Inheritance
% **H. Conrad Cunningham**
% **16 September 2018**

---
lang: en
--- 

Copyright (C) 2018, H. Conrad Cunningham 

**Acknowledgements**: I created these slides in Fall 2018 from an
older set of slides (2004) that was loosely based on Chapter 8 of
Timothy Budd's textbook *Understanding Object-Oriented Programming
with Java, Updated Edition*, Addison-Wesley, 2000.

**Browser Advisory**:
The HTML version of this document may require use of a browser that
supports the display of MathML. A good choice as of September 2018 is
a recent version of Firefox from Mozilla.


# Understanding Inheritance {.center}


## Motivation

Use inheritance to create new software structures from existing
software units to:

-   improve productivity

-   enhance quality


## Generality and Specialization


Conflict: 

-   Specific projects usually require *specialized* software

-   Reusability usually requires *general* software

Resolution?

-   Inheritance allows general software to be specialized for project


## Abstract Idea

TODO


## Practical Meaning of Inheritance

In programming languages, inheritance means:

-   Data and behavior of parent class are part of child

-   Child class may include data and behavior not in parent


With respect to parent class, child class is, in some sense

-   An extension -- larger set of properties

-   A contraction -- more specialized (restricted) objects


## Idealized Image of Inheritance

Consider[ ]{.Apple-converted-space}**]{.s1}

-   Subclass instances must possess all data areas of parent

-   Subclass instances must implement all functionality of parent

Thus

-   Subclass instance should be *indistinguishable* from parent class
    instance --- child can be substituted for parent


## Principle of Substitutability

If C is a subclass of P, instances of C can be substituted for
instances of P in any situation with no observable effect.

(Liskov Substitution Principle)


## Subclass and Subtype (1) 

Subtype:
:   Class that satisfies principle of substitutability

Subclass:
:   Object constructed using inheritance, whether or not satisfies
    principle of substitutability


## Subclass and Subtype (2) 

Independent concepts

-   Not all subclasses are subtypes

-   Sometimes subtypes constructed without being subclasses


## Forms of Inheritance (1)
 
1.  **Specialization:** Child class is special case (subtype) of parent

2.  **Specification;** Parent class defines behavior implemented in
    child, but not in parent

3.  **Construction:** Parent class used only for its behavior ---
    child class not subtype --- no *is-a* relationship to parent

4.  **Generalization:** Child class modifies/overrides some parent
    methods, extends behavior to more general kind of object

## Forms of Inheritance (2)
 
5.  **Extension:** Child class adds new functionality to parent, but
    does not change any inherited behavior

6.  **Limitation:** Child class limits some behaviors of parent

7.  **Variance:** Child and parent class are variants of each other
    --- inheritance to allow code sharing --- arbitrary relationship

8.  **Combination:** Child class inherits features from multiple
    parents --- multiple inheritance


## [1] Specialization

-   Child class special case (subtype) of parent 

-   Most common form of inheritance

-   Example: `Professor` specialized form of `Employee`

-   Child may override behavior of parent to specialize

-   Child satisfies specification of parent in all relevant
    aspects --- preserves substitutability


## [2] Specification*

-   Parent class defines *behavior*, but does not implement it

-   Child implements behavior

-   Second next most common form of inheritance

-   Example: class ]{.s1}[StackInArray]{.s12}[ gives implementations for
method signatures defined in abstract class
]{.s1}[Stack]{.s12}[[ ]{.Apple-converted-space}]{.s1}

[[ ]{.Apple-tab-span}*Java and Scala:* ]{.s13}[StackInArray extends
Stack[ ]{.Apple-converted-space}]{.s1}

[Example: class ]{.s1}[ArrayRankedSeq]{.s12}[ gives implementations for
method signatures defined in Java interface or Scala trait
]{.s1}[RankedSequence]{.s12}[[ ]{.Apple-converted-space}]{.s1}

[[ ]{.Apple-tab-span}*Java:*[ ]{.Apple-converted-space}]{.s13}[
ArrayRankedSeq implements
RankedSequence[ ]{.Apple-converted-space}]{.s1}

[[    ]{.Apple-converted-space}*Scala:* ]{.s13}[ArrayRankedSeq extends
RankedSequence[ ]{.Apple-converted-space}]{.s1}

[**Forms of Inheritance**]{.s14}[**\
[ ]{.Apple-converted-space}**]{.s2}[**Specification (continued)**]{.s1}

[**Parent class defines** ]{.s1}[**behavior**]{.s11}[ **implemented in
child, but not parent[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[...]{.s1}

[Subclasses are realizations of incomplete abstract
specification[ ]{.Apple-converted-space}]{.s1}

[Defines common interface for group of related
classes[ ]{.Apple-converted-space}]{.s1}

[Preserves substitutability]{.s1}[[ ]{.Apple-converted-space}]{.s8}

[**Forms of Inheritance**]{.s1}[**\
**]{.s6}[**Construction**]{.s9}

[**Parent class used only for its behavior --- child class not subtype
--- no *is-a* relationship to
parent**]{.s1}[**[ ]{.Apple-converted-space}**]{.s15}

[]{.s1}\

[Sometimes used for convenience, but
discouraged[ ]{.Apple-converted-space}]{.s1}

[Example: extending ]{.s1}[List]{.s10}[ class to develop
]{.s1}[Set]{.s10}[, without \"hiding\" unneeded
methods[ ]{.Apple-converted-space}]{.s1}

[Example: extending a byte-based I/O stream to a stream for handling
other objects[ ]{.Apple-converted-space}]{.s1}

[Often violates substitutability[ ]{.Apple-converted-space}]{.s1}

[More common in dynamically typed languages (e.g., Smalltalk, Ruby) than
in statically typed (e.g., Java, Scala)[ ]{.Apple-converted-space}]{.s1}

[Can sometimes use aggregation (composition)
instead[ ]{.Apple-converted-space}]{.s1}

[**Forms of Inheritance**]{.s1}[**\
[ ]{.Apple-converted-space}**]{.s6}[**Generalization**]{.s9}

[**Child class modifies or overrides some methods of parent, extends
behavior to more general kind of
object[ ]{.Apple-converted-space}**]{.s1}

[Sometimes used for convenience (or necessity), but
discouraged[ ]{.Apple-converted-space}]{.s1}

[Example: graphics ]{.s1}[Window]{.s10}[ generalized to
]{.s1}[ColorWindow]{.s10}[ (with background
color)[ ]{.Apple-converted-space}]{.s1}

[Opposite of specialization---violates
substitutability[ ]{.Apple-converted-space}]{.s1}

[Used when must build from fixed, difficult-to-modify set of
classes[ ]{.Apple-converted-space}]{.s1}

[Where possible, invert class hierarchy or use
aggregation[ ]{.Apple-converted-space}]{.s1}

[**Forms of Inheritance\
**]{.s1}[**[ ]{.Apple-converted-space}**]{.s6}[**Extension**]{.s9}

[**Child class adds new functionality to parent, but does not change any
inherited behavior**]{.s1}[**[ ]{.Apple-converted-space}**]{.s7}

[]{.s1}\

[Useful technique to give new behaviors to existing base class that
cannot be modified[ ]{.Apple-converted-space}]{.s1}

[Example: ]{.s1}[StringSet]{.s10}[ extends ]{.s1}[Set]{.s10}[, adding
string-related methods (e.g, prefix
search)[ ]{.Apple-converted-space}]{.s1}

[Preserves substitutability[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**Forms of Inheritance**]{.s1}[**\
**]{.s6}[**Limitation**]{.s9}

[**Child class limits some of the behavior of
parent[ ]{.Apple-converted-space}**]{.s1}

[Sometimes used for convenience, but strongly
discouraged[ ]{.Apple-converted-space}]{.s1}

[Example**:**]{.s1}[ Stack]{.s10}[ extends
]{.s1}[DoubleEndedQueue]{.s10}[, replacing unneeded methods to give
error messages[ ]{.Apple-converted-space}]{.s1}

[Violates substitutability[ ]{.Apple-converted-space}]{.s1}

[Used when must build from fixed, difficult-to-modify set of
classes[ ]{.Apple-converted-space}]{.s1}

[Avoid when possible, perhaps use
aggregation]{.s1}[[ ]{.Apple-converted-space}]{.s4}

[**Forms of Inheritance\
**]{.s1}[**[ ]{.Apple-converted-space}**]{.s6}[**Variance[ ]{.Apple-converted-space}**]{.s9}

[**Child and parent class are variants of each other---inheritance to
allow code sharing---arbitrary relationship**]{.s1}

[[ ]{.Apple-converted-space}]{.s1}

[Sometimes used for convenience, but
discouraged[ ]{.Apple-converted-space}]{.s1}

[Example: graphics ]{.s1}[Tablet ]{.s10}[class extending
]{.s1}[Mouse]{.s10}[ to share similar control
code[ ]{.Apple-converted-space}]{.s1}

[Violates substitutability[ ]{.Apple-converted-space}]{.s1}

[Better to define more general parent class like
]{.s1}[PointingDevice[ ]{.Apple-converted-space}]{.s10}

[**Forms of Inheritance**]{.s1}[**\
[ ]{.Apple-converted-space}**]{.s6}[**Combination**]{.s9}

[**Child class inherits features from more than one parent---multiple
inheritance**]{.s1}[**[ ]{.Apple-converted-space}**]{.s7}

[]{.s1}\

[Example: ]{.s15}[GraduateInstructor ]{.s1}[might inherit from both
]{.s15}[GraduateStudent]{.s1}[ and
]{.s15}[Faculty]{.s1}[[ ]{.Apple-converted-space}]{.s15}

[Often difficult to understand and to implement
language[ ]{.Apple-converted-space}]{.s1}

[Often use to \"mix-in\" specification of another role or
protocol[ ]{.Apple-converted-space}]{.s1}

[**Forms of Inheritance**]{.s14}[**\
[ ]{.Apple-converted-space}**]{.s2}[**Combination (continued)**]{.s1}

[**Child class inherits features from more than one parent---multiple
inheritance**]{.s1}[**[ ]{.Apple-converted-space}**]{.s7}

[]{.s1}\

[...]{.s1}

[C++ has multiple inheritance via subclassing, with some semantic
difficulties]{.s1}

[Java has single inheritance via subclassing (extends), but multiple
inheritance for specification via interface implementations
(implements)]{.s1}[[ ]{.Apple-converted-space}]{.s4}

[Scala has single inheritance via subclassing and multiple "mix-in"
inheritance of "stackable" traits (avoiding semantic issues of
C++)]{.s1}

[**Inheritance and Assertions[ ]{.Apple-converted-space}**]{.s1}

[**Suppose C is a subtype of P**]{.s1}

[P and C have ]{.s1}[interface invariants]{.s2}[ I and IC,
respectively[ ]{.Apple-converted-space}]{.s1}

[meth() is a public method of P with precondition Q and postcondition
R[ ]{.Apple-converted-space}]{.s1}

[meth() in C has precondition QC and postcondition
RC[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**Subtype C should not violate I, Q, and R**]{.s1}

[IC implies I -- may strengthen invariant -- extend interface and
data[ ]{.Apple-converted-space}]{.s1}

[Q implies QC -- may weaken precondition -- expand valid
inputs[ ]{.Apple-converted-space}]{.s1}

[RC implies R \-- may strengthen postcondition -- restrict valid
outputs[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**Abstract preconditions can enable controlled \"strengthening\" of
precondition**]{.s1}[**[ ]{.Apple-converted-space}**]{.s8}

[Consider BoundedStack inheriting from an unbounded Stack
class[ ]{.Apple-converted-space}]{.s1}

[Give method push() a \"not full\" precondition -- always true in
Stack[ ]{.Apple-converted-space}]{.s1}

[Refine \"not full\" in subclass BoundedStack to be true or
false[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**Inheritance and**]{.s1}[ ]{.s7}[**Assertions**]{.s1}

[**Trees versus Forests[ ]{.Apple-converted-space}**]{.s1}

[**Two common views of class hierarchies**]{.s1}

[**Tree**]{.s1}

[All classes are part of single class
hierarchy[ ]{.Apple-converted-space}]{.s1}

[Advantage: root\'s functionality inherited by all objects -- all have
basic functionality[ ]{.Apple-converted-space}]{.s1}

[Disadvantage: tight coupling of classes, large libraries for an
application[ ]{.Apple-converted-space}]{.s1}

[Languages: Java\'s classes, Scala's classes, Smalltalk, Objective C,
Delphi Object Pascal]{.s1}

[]{.s1}\

[Forest**[ ]{.Apple-converted-space}**]{.s1}

[Classes only placed in hierarchies if they have a relationship -- many
small hierarchies.[ ]{.Apple-converted-space}]{.s1}

[Advantage: smaller libraries of classes for application, less coupling
possible[ ]{.Apple-converted-space}]{.s1}

[Disadvantage: no shared functionality among all
objects[ ]{.Apple-converted-space}]{.s1}

[Languages: Java\'s interfaces, Scala's traits, C++, Apple Object
Pascal[ ]{.Apple-converted-space}]{.s1}

[**Tree versus Forest**]{.s1}

[**Trees versus Forests**]{.s1}

[**Forest**]{.s1}

[**Inheritance in Java[ ]{.Apple-converted-space}**]{.s1}

[**Tree-structured class hierarchy (with primitive data types not in
hierarchy)[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**Forest-structured interface
hierarchy[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**Modifiers for classes/interfaces[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**Access modifiers for class/interface features**]{.s1}

[**Inheritance in Java**]{.s14}[\
]{.s5}[**Tree-structured Class Hierarchy**]{.s1}

[Root class is
]{.s4}[**java.lang.Object**]{.s1}[[ ]{.Apple-converted-space}]{.s4}

[Other classes extend exactly one other class]{.s1}

[**default is**
]{.s1}[**Object**]{.s16}[**[ ]{.Apple-converted-space}**]{.s1}

[Declaration uses keyword ]{.s1}[**extends**]{.s17}[ after class
name[ ]{.Apple-converted-space}]{.s1}

[**Inheritance in Java\
**]{.s14}[**Forest-structured Interface Hierarchy**]{.s1}

[**interface**]{.s16}[ defines an interface
specification[ ]{.Apple-converted-space}]{.s1}

[**implements**]{.s16}[ after class name to promise implementation of
interface -- inheritance for
specification[ ]{.Apple-converted-space}]{.s1}

[An interface extends zero or more other
interfaces[ ]{.Apple-converted-space}]{.s1}

[A class implements zero or more interfaces]{.s1}

[**public interface Queue[ ]{.Apple-converted-space}**]{.s1}

[**{** ]{.s18}[**// signatures of public methods // Queues must
provide**]{.s1}[**[ ]{.Apple-converted-space}**]{.s18}

[**}[ ]{.Apple-converted-space}**]{.s1}

[**public class QueueAsLinkedList implements
Queue[ ]{.Apple-converted-space}**]{.s1}

[**{** ]{.s18}[**// includes implementations**]{.s1}

[**[  ]{.Apple-converted-space}// of the Queue
methods**]{.s1}[**[ ]{.Apple-converted-space}**]{.s18}

[**}**]{.s1}

[**Inheritance in Java**]{.s14}[**\
**]{.s5}[**Visibility Modifiers for Class/Interface Features**]{.s1}

[**public**]{.s19}[ features accessible from anywhere in
program[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**private** ]{.s19}[features accessible from inside class
only[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[Default-access (i.e., \"friendly\") features accessible from inside the
current Java package[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**protected** ]{.s19}[features accessible in package or inside any
child class[ ]{.Apple-converted-space}]{.s1}

[**Inheritance in Java**]{.s1}

[**public abstract class Stack[ ]{.Apple-converted-space}**]{.s1}

[**{ [  ]{.Apple-converted-space}// extends Object by
default[ ]{.Apple-converted-space}**]{.s1}

[**[    ]{.Apple-converted-space}// data definitions plus signatures
and[ ]{.Apple-converted-space}**]{.s1}

[**[    ]{.Apple-converted-space}// possibly implementations of
methods[ ]{.Apple-converted-space}**]{.s1}

[**}[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**public class StackInArray extends
Stack[ ]{.Apple-converted-space}**]{.s1}

[**{ // extended features plus overridden
implementations[ ]{.Apple-converted-space}**]{.s1}

[**}[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**public interface Queue[ ]{.Apple-converted-space}**]{.s1}

[**{ // signatures of public methods Queues must
provide[ ]{.Apple-converted-space}**]{.s1}

[**}[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**public class QueueAsLinkedList implements
Queue[ ]{.Apple-converted-space}**]{.s1}

[**{ // includes implementations of the Queue
methods[ ]{.Apple-converted-space}**]{.s1}

[**}**]{.s1}

[**Facilities of Root Class Object**]{.s1}

[**Minimum functionality for all objects include**]{.s1}

[]{.s1}\

[**equals(Object obj)**]{.s1}[**[ ]{.Apple-converted-space}**]{.s20}

[is ]{.s1}[**obj**]{.s16}[ the same as
receiver?]{.s1}[[ ]{.Apple-converted-space}]{.s21}

[]{.s1}\

[**toString()[ ]{.Apple-converted-space}**]{.s1}

[converts the object to a string value[ ]{.Apple-converted-space}]{.s1}

[]{.s1}\

[**hashCode()[ ]{.Apple-converted-space}**]{.s1}

[return a default hashcode for the
object]{.s1}[[ ]{.Apple-converted-space}]{.s21}

[]{.s1}\

[**getClass()[ ]{.Apple-converted-space}**]{.s1}

[return an identifier for the class of the
object]{.s1}[[ ]{.Apple-converted-space}]{.s21}

[]{.s1}\

[**First three above are often overridden in
classes.**]{.s1}[**[ ]{.Apple-converted-space}**]{.s8}

[**Inheritance in Scala[ ]{.Apple-converted-space}**]{.s1}

[**Tree-structured class hierarchy (with primitives in
hierarchy)**]{.s1}

[**Classes that extend one class and "mix-in" zero or more
traits**]{.s1}

[]{.s1}\

[**Modifiers for classes/traits**]{.s1}

[]{.s1}\

[**Access modifiers for class/interface features (slightly different
from Java)**]{.s1}

[**Inheritance in Scala**]{.s14}[\
]{.s5}[**Tree-structured Class Hierarchy**]{.s1}

[Root class is ]{.s1}[**Any**]{.s10}[[ ]{.Apple-converted-space}]{.s1}

[Primitive[  ]{.Apple-converted-space}value types extend
]{.s1}[AnyVal]{.s10}

[All reference object types extend ]{.s1}[AnyRef]{.s10}[
]{.s16}[(java.lang.Object)]{.s22}

[Scala reference objects also mix-in trait]{.s1}[ ScalaObject]{.s10}

[Scala traits extend]{.s1}[ ]{.s16}[AnyRef]{.s10}

[**Inheritance in Scala**]{.s1}

[]{.s1}\

[**trait Philosphical {**]{.s1}

[**[  ]{.Apple-converted-space}//method signatures, perhaps
implementations**]{.s1}

[**[  ]{.Apple-converted-space}// [  ]{.Apple-converted-space}perhaps
data attributes**]{.s1}

[**}[ ]{.Apple-converted-space}**]{.s1}

[**class Frog extends Philosphical { . . . }**]{.s1}

[**trait HasLegs { . . . }**]{.s1}

[**class Animal [ ]{.Apple-converted-space}**]{.s1}

[**class Frog extends Animal with Philosphical[ 
]{.Apple-converted-space}with HasLegs { ... }**]{.s1}

[**[  ]{.Apple-converted-space}**]{.s1}

[**Inheritance in Scala**]{.s14}[**\
**]{.s5}[**Visibility Modifiers for Class/Trait Features**]{.s1}

[]{.s1}\

[**private** ]{.s19}[features accessible from inside class only (like
Java except for inner classes)]{.s1}

[**protected** ]{.s19}[features accessible only from subclasses (more
restricted than Java)]{.s1}

[No access modifier means[  ]{.Apple-converted-space}"public" access
features accessible from anywhere]{.s1}

[private\[X\]]{.s23}[ and ]{.s1}[protected\[X\] ]{.s23}[provide
qualified access "up to ]{.s1}[X]{.s23}[" -- gives capabilities like
object private, package protected, etc.]{.s1}

[]{.s1}\

[]{.s1}\

[**Facilities of Root Classes\
Any and AnyRef**]{.s1}

[]{.s1}\

[**... Look in the API documentation**]{.s1}

[**Benefits of Inheritance**]{.s1}

[**Software reusability (among
projects)[ ]{.Apple-converted-space}**]{.s1}

[**Code sharing (within a project)[ ]{.Apple-converted-space}**]{.s1}

[**Increased reliability (resulting from reuse and sharing of
well-tested code)[ ]{.Apple-converted-space}**]{.s1}

[**Consistency of interface (among related
objects)[ ]{.Apple-converted-space}**]{.s1}

[**Rapid prototyping (quickly assemble from pre-existing
components)[ ]{.Apple-converted-space}**]{.s1}

[**Polymorphism and frameworks (high-level reusable
components)[ ]{.Apple-converted-space}**]{.s1}

[**Information hiding[ ]{.Apple-converted-space}**]{.s1}

[**Costs of Inheritance**]{.s1}

[**Execution speed[ ]{.Apple-converted-space}**]{.s1}

[]{.s1}\

[**Program size**]{.s1}

[]{.s1}\

[**Message-passing overhead**]{.s1}

[]{.s1}\

[**Program complexity**]{.s1}

[**Acknowledgement**]{.s1}

[**[   ]{.Apple-converted-space}The development of the original
Java-based slides was supported by a grant from Acxiom Corporation
titled "The Acxiom Laboratory for Software Architecture and Component
Engineering (ALSACE)."**]{.s1}

[]{.s1}\

[**Students who helped with slides---Jian Li, Yi Liu, Pallavi Tadepalli,
etc.**]{.s1}
