- polymorphism - making the type system more flexible, but still safe
- casting - eliminates differences between types; int and float;
destructive (lost precision) and complicated (casting between a double
and a string)
- overloading - makes many types respond to the same operators; int,
float, and string addition; semantically dubious (string
multiplication) and complicated (string multiplication, conversions and
the n-by-m problem)
- templates - abstracts away types when not important; the size of a
T list; implementation problems (code bloat, funny rules), some
type aspects are important (equal T values)
- subtype polymorphism - related types exhibit similar behaviors
- example - numbers
- there are many number types (natural, integer, rational,
floating point, complex); they all respond to arithmetic operators
- casting and templates are not appropriate (information loss and type
specific operators)
- overloading (without casting) is appropriate, but how should it be
organized
- subtype polymorphism models the behavioral similarities among a set of
related types
- general approach
- a parent class models the abstract, generic behavior of the related
types as an abstract, generic type - for example,
class Number
- each specific type is modeled as a child of the parent class - for
example,
class Integer : Number
or class Complex : Number
- rule of thumb - the longest path from root to leaf should be short,
two or three classes
- longer paths are complicated because information is spread out
- how does subtype polymorphism work - inheritance
- inheritance provides both prototype sharing and polymorphism
- parent prototypes are copied to the children - behavioral sharing
- "behavior" means behavior at the prototype, not code
sharing
- defines the consistent behavior property among the related types
- polymorphism comes from the parent-child relation - is-a inheritance
- a child type is-a kind of parent type - an integer is a kind of
number
- shared prototypes makes is-a inheritance useful - the child really
is-a kind of parent
- recognizing subtype polymorphism
- it should be designed into the code
- reduces design effort - design the parent class once and the child
classes follow along
- reduces coding effort - the parent-child relation neatly and clearly
factors and emphasizes coding obligations
- increases syntactic clarity - the parent class sets the notation
(operators) for all its children, rather than having notation
specific to each child
- increases semantic clarity - a number is a number, and it gets added
- missed opportunities for subtype polymorphism smell like type-based if
or case statements
- for example - from my solution to programming assignment 3
- an expression is a node; a node is one of three types: number,
variable, or operation
void expression::write(ostream & os) const {
if (expr_t == operation) {
left->write(os);
os << " " << prep << " ";
right->write(os);
}
else if (expr_t == number)
val.write(os);
else {
assert(expr_t == variable)
os << prep;
}
}
- define the parent
class node
and the children class
number_node : node
, class variable_node : node
, and class
operator_node : node
- for example - adapted from the text
- a student record can be for a graduate or undergraduate
if (ch == 'u')
record.type = undergrad;
// read undergrad information
else
record.type = graduate;
// read graduate information
- define a parent
class record
and children class grad_rec :
record
and class ugrad_rec : record
- the book does something slightly different and slightly less clean
- points to remember
- missed subtype polymorphism looks like type-based if or case statements
- design for subtype polymorphism
- what things behave similarly (have the same set of prototypes) -
these are the child classes
- what is the common set of similar behaviors - this is the parent
class
- use inheritance to share prototypes, not code - "behavior"
means prototype, not code
- code-sharing inheritance was the oo tragedy of the '80s
- code-sharing inheritance hierarchies are narrow, brittle, and complex
- break this rule only under subtype polymorphism
- factor common code from the children into the parent
- don't force parent code on the children
This page last modified on 9 April 2002.