Strict Inheritance
Object-Oriented Programming
236703
Spring 2008
1
Varieties of Polymorphism
Polymorphism
Ad hoc
Coercion
Overloading
Universal
Inclusion
Sub-type
Parametric
Ad hoc vs. Universal Polymorphism
• Universal:
– Polymorphism is over infinitely many types.
– The different shapes are generated automatically.
– There is a unifying, common ground to all the different shapes
the polymorphic entity may take.
• Ad hoc:
– Polymorphism is over finitely few shapes:
• often, very few.
– Different shapes are generated manually, or semi-manually.
– No unifying common ground to all shapes, other than
designer’s intentions.
• Uniformity is a coincidence, not a rule.
Strict Inheritance and the Different
Parts of a Class
• Structure
– The structure of the derived class is an extension of that of the base
class
• Protocol
– The derived class is a subtype of the base class
• Behavior
– The derived class implements only the new protocol elements
• Forge
– The derived class has a new forge
• Mill
– The derived class has a new mill
– Usually , must invoke the mill of the base class.
4
Properties of Strict Inheritance
• New abstraction mechanism: extend a given class
without touching its code.
• Conformance (AKA substitutability)
– If a class B inherits from another class A, then the objects of B
can be used wherever the objects of A are used.
• Benefits of strict inheritance:
– No performance penalty.
• Compile-time creature.
• Can be thought of as a syntactic sugar which helps define classes.
– No conceptual penalty.
• Structured path for understanding the classes.
• Drawbacks of strict inheritance:
– Not overly powerful!
Inclusion Polymorphism and OOP
• Suppose that the function fire() expects an instance of class
Employee.
• Then, it will also accept an instance of class Manager, provided
that Manager (strictly) inherits from Employee.
– Manager has everything Employee has
• (in exactly the same form!)
– The additional operations in Manager will not be used in fire()
• We say that the type Manager is a subtype of the type Employee.
• We say that the type Employee includes the type Manager.
• The polymorphism in this case is a result of subtyping, or type
inclusion.
Methods are Polymorphic
Employee
Manager
e;
m;
e.raise_salary(10); // OK
m.raise_salary(10); // OK
e.is_manager_of(...);
// Error
m.is_manager_of(E);
// OK
Employee
raise_salary
Manager
is_manager_of
• The code of the raise_salary method is
Polymorphic.
• It can be applied to all subtypes (subclasses) of
Employee.
• We see that without polymorphism, inheritance makes
very little sense.
Polymorphic Objects
• All variables in Smalltalk are polymorphic.
They may store instances of all classes.
• this is a polymorphic object. It may point to
things of different subtypes at different times.
– A pointer to an inherited type is generated
whenever an inherited method is called.
• In fact, all class pointers and all class
references in C++ are polymorphic...
Pointers as Polymorphic Objects
Employee
Manager
e, *pE;
m, *pM;
Employee
pE
Manager
E
pM
Employee
M
Manager
Rules for pointer mixing:
pE
pM
pE
pM
=
=
=
=
&e;
&m;
&m;
&e;
//
//
//
//
OK - Ordinary C type rules
OK - Ordinary C type rules
OK - Pointers are polymorphic!
Compile time error
References as Polymorphic Objects
E
Employee
Employee
M
Manager
Manager
ostream& operator << (
ostream &, const Employee &
);
Employee e;
Manager
m;
Employee &eRef1 = e; // OK!
Employee &eRef2 = m; // OK! Reference to subobject
Manager &mRef1 = e; // Compile time error!
Manager &mRef2 = m; // OK!
cout << e << m;
// OK! Reference to subobject
Up-Casting
• Casting: A synonym for coercion from a derived type
to the base type.
Employee
• Up-casting: casting pointers up the
raise_salary
inheritance hierarchy.
– Up-casting of this occurs implicitly
whenever an inherited method is called.
Employee
Manager
e;
m;
Manager
is_manager_of
m.is_manager_of(e);
// Type of this is Manager *.
// No casting occurs.
m.raise_salary(10);
// Type of this is Employee *
// in raise_salary.
// Up casting must occur.
Down-Casting
Down-Casting: casting pointers and
references down the inheritance hierarchy:
– Must be done explicitly.
pE
E
Employee
Employee
Manager
pE = &m;
m = *pE;
e, *pE;
m, *pM;
M
Manager
// OK: implicit upcasting.
// Error: implicit downcasting is not allowed
// explicit down casting:
m = *(Manager *)pE;
// deprecated syntax
m = *static_cast<Manager*>pE; // recommended syntax
// Either way, you better know what you are doing!
Value Semantics, Coercion & Polymorphism
• Polymorphism is applicable to code and variables but not
to values.
• Coercion: translation from a value of one type to a value
of a different type. Often with some loss of contents.
– Example: coercion from integer to real and vice versa.
• Inheritance in C++: defines a coercion from the derived
class to the base class.
– The coercion is parametric! It works for all subtypes!
• Coercion is done by extracting the subobject.
What are Subobjects?
class Base {
// ...
};
class Derived: public Base
{
// ...
};
• Each object of class Derived has a subobject
of class Base
• It is possible in many cases to relate to that
subobject
Mixing Values
E
Employee
M
Manager
Employee
Manager
e;
m;
1. call the (compiler generated) type casting
operator from Manager to Employee
2. call the (compiler-defined or user-defined)
Employee to Employee assignment operator.
Rules for Mixing Values
e = m; // OK - Valid coercion: truncation will occur.
m = e; // Error - No coercion is defined.
// Manager is an Employee but not vice-versa!
Arrays of Values
Employee
Manager
department[10];
management[10];
• department and management are not compatible in
any way.
• In general, sizeof Employee <= sizeof Manager
– Usually, sizeof Employee < sizeof Manager
• Therefore, an array of managers (usually) occupies more
space than an array of the same size of employees, and the
conversion between the two is not trivial.
• This is just like an array of char which is not compatible at
all with an array of int
– Although char and int are compatible in some operations.
Arrays of Pointers
It is often convenient to define mixed type collections. The
simplest and easiest way to do so is to use an array of pointers
to the base class.
Employee
*department[100];
It is easy to deposit objects into the above array, however,
determining the type of object that resides in a certain location
requires down casting.
Down casting should be used only in extremely special cases. In
this common situation, what should be used instead is dynamic
binding.
Java Array Subtyping
In Java, if class Manager is a subtype of class Employee,
then Manager[] is a subtype of Employee[]
Employee ee[];
Manager
mm[];
Manager[ ] mArr = new Manager[10];
Employee[ ] eArr = mArr; // OK
eArr[0] = new Employee(); // compiles, but run-time error
// raises ArrayStoreException
© Copyright 2026 Paperzz