Polymorphism (Budd's UOOPJ, Ch. 12)

Download Report

Transcript Polymorphism (Budd's UOOPJ, Ch. 12)

Engr 691
Special Topics in Engineering Science
Software Architecture
Spring Semester 2004
Lecture Notes
Polymorphism
(Budd's UOOPJ, Ch. 12)
This is a set of "slides" to accompany
chapter 12 of
Timothy Budd's textbook
Understanding Object-Oriented Programming with Java,
Updated Edition
(Addison-Wesley, 2000)
Definition
Polymorphous:
– Having, or assuming, various forms, characters, or
styles (Webster's Collegiate Dictionary, Fifth Edition).
Term used in several different ways in computer
science
Polymorphism in
Programming Languages
A variable holding a value drawn from a
group of types
A name associated with several different
function bodies
A single function with polymorphic
variables as parameters
Polymorphism in
Untyped Languages
Polymorphism is trivial issue in untyped languages
All variables are potentially polymorphic
Variables take on type of their values dynamically
silly: x
" a silly Smalltalk polymorphic method "
(x isKindOf: Integer) ifTrue: [ ^ x + 1 ] .
(x isKindOf: Fraction) ifTrue: [ ^ x reciprocal ].
(x isKindOf: String) ifTrue: [ ^ x reversed ] .
^ nil
Forms of Polymorphism
polymorphic variables (assignment polymorphism)
overloading (ad hoc polymorphism)
overriding (inclusion polymorphism)
deferred (abstract) methods
pure polymorphism (functions with polymorphic
parameters)
generics or templates
Polymorphic Variables
Variable declared as one class can hold values
from subclass
Dynamic (run-time) type must be subclass of
static (declared) type
In C++, only works with pointers and references
Polymorphic variables (or values) basis for
power of OOP
Overloading
A single function name denoting two or more function bodies is
overloaded
Common example: + means both integer and floating addition
In Java, + also used for string concatenation
Determination of which function to execute made by examining
argument/return types
Bound either at compile-time or at run-time depending on language
Should not be confused with overriding or refinement – functions
need not be related by classes
Should not be confused with coercion (casting) – one type is
converted into another for operation
Overloading Example: Florist
class Spouse
{
public void sendFlowersTo(Address inAddress)
{
go to florist;
give florist message
sendFlowersTo(anAddress);
}
}
Overloading Example: Florist
class Florist
{
public void sendFlowersTo(Address anAddress)
{
if (address is nearby)
{
make up flower arrangement;
tell delivery person sendFlowersTo(anAddress);
} else {
look up florist near anAddress;
contact other florist;
give other florist message sendFlowersTo(anAddress);
}
}
}
Above the sendFlowersTo methods are semantically related but not
related via inheritance
Methods with same name not necessarily related semantically
Overloading and
Type Signatures
Selection of which procedure to execute based on type
signature
– the number, types, and order of parameters
– parametric overloading
Often used in constructors
C++ and Java allow functions in same scope to have
same name if signatures differ
C++ also allows extensive overloading of operator
symbols
Overloading and
Type Signatures (continued)
Polymorphic symbol << used for both left shift and stream
output – latter also overloaded by type of value
stream
stream
stream
stream
stream
<<
<<
<<
<<
<<
integer;
char;
char *;
double;
complex;
Overriding
Overriding occurs when child class changes meaning of
function from parent
Different child classes can override in different ways
– replacement or refinement
Parent class can have default behavior; child classes
alternatives
Contributes to code sharing
Ensures common interfaces
Example: Comparisons
abstract class Magnitude {
public boolean lessOrEqual(Magnitude arg)
throws IncomparableMagnitudeException {
return (this.lessThan(arg) || this.equals(arg));
}
}
public boolean greaterOrEqual(Magnitude arg)
throws IncomparableMagnitudeException {
return arg.lessOrEqual(this);
}
public boolean lessThan(Magnitude arg)
throws IncomparableMagnitudeException {
return this.lessOrEqual(arg) && ! this.equals(arg);
}
public boolean greaterThan(Magnitude arg)
throws IncomparableMagnitudeException {
return arg.lessThan(this);
}
Example: Comparisons
(continued)
class IncomparableMagnitudeException extends Exception
{
public IncomparableMagnitudeException() { }
public IncomparableMagnitudeException(String msg)
{ super(msg); }
}
To define all six comparisons in a noncircular manner,
subclasses must:
Override class Object method equals() if default not appropriate
Override class Magnitude method lessThan() or lessOrEqual()
Example: Comparisons
(continued)
class Point extends Magnitude
{
public Point(int x0, int y0)
{ x = x0; y = y0; }
}
public boolean lessThan(Magnitude arg)
throws IncomparableMagnitudeException {
if (arg instanceof Point) {
Point p = (Point) arg; // less if lower left quadrant
return x < p.x && y < p.y; // of this point
} else throw new IncomparableMagnitudeException();
}
private int x; private int y;
Note: The above method uses inheritance by limitation because of the
check for the Point type and throwing the exception
Deferred (Abstract) Methods
Deferred method is special case of overriding
Parent class gives type signature, but provides no implementation
Child class must provide an implementation
Usually combined with other techniques
Method included in parent class because it fits in abstraction, although no
concrete definition may be possible at that level
 semantics of abstract methods should be specified carefully – e.g., using preand postconditions.
 subclasses should adhere to specification
Allows the deferred method to be applied to polymorphic variables of the
parent type
In Java, use abstract modifier for method
Pure Polymorphism
Pure polymorphism usually means functions with polymorphic parameters
(including receiver)
Method between (like the other methods of Magnitude) exhibits pure
polymorphism
class Magnitude
{
...
public boolean between(Magnitude low, Magnitude high)
throws IncomparableMagnitudeException {
return low.lessOrEqual(this) &&
this.lessOrEqual(high);
}
}
Works for any receiver or arguments of parent type Magnitude (generates
exception if of incomparable types)
Pure Polymorphism (continued)
Code below would print "Is Between"
Point p = new Point(0,0);
Point q = new Point(10,10);
Magnitude r = new Point(0,0);
if (r.between(p,q))
System.println("Is Between");
else
System.println
("Is Not Between");
Pure Polymorphism (continued)
Message r.between(p,q) has the following trace of dynamic binding:













In code above, checks for between() in Point, not found
In code above, checks for between() in Magnitude, found, binds call
In Magnitude.between, checks for lessOrEqual() in Point, not found
In Magnitude.between, checks for lessOrEqual() in Magnitude, found, binds
call
In Magnitude.lessOrEqual, checks for lessThan() in Point, found, binds call
In Point.lessThan, returns false since (0,0) is not less than (0,0)
In Magnitude.lessOrEqual, checks for equals() in Point, not found
In Magnitude.lessOrEqual, checks for equals() in Magnitude, not found
In Magnitude.lessOrEqual, checks for equals() in Object, found, binds call
In Object.equals, returns true
In Magnitude.lessOrEqual, returns true since (0,0) <= (0,0)
Similar for comparison of (0,0) and (10,10) ...
In Magnitude.between, returns true since (0,0) <= (0,0) and (0,0) <= (10,10), l
Note that polymorphism (dynamic binding) takes more execution time than
a static binding
Generics and Templates
A type can be used as a parameter in class description
C++ example:
}
template <class T> class Link
{
public:
...
private:
T value;
Link * nextLink;
Generics and Templates
(continued)
Declaration of variable provides the actual type
 Link<Shape> sl;
 Declaration above makes s1 a Link variable that has
a value of type Shape
Generics not supported in Java currently, but
may be in the future
 Keyword generic reserved
 Experimental versions of Java do support generics
Review of Polymorphism in Java
Polymorphic variables? Yes
 Tree-structured subclass hierarchy using inheritance
(extends)
 Subtype hierarchies using interfaces (implements)
 Variables declared with either class or interface as
type
 Variables can hold value from subclass or interface
subtype
Overloading? Yes
 Overloading of method names (including in same
class with parametric overloading)
 No user-defined overloading of operator symbols
Review of Polymorphism in Java
Overriding? Yes
 By default, all methods can be overridden
 Keyword final prevents overriding
Deferred methods? Yes
 Keyword abstract for deferred methods, signature but no
body
Pure polymorphism? Yes
 Dynamic binding of call to method, searching up subclass
hierarchy
Generics? No
 Perhaps in future
 Experimental versions such as GJ (Generic Java)
Efficiency and Polymorphism
Programming always involves compromises
Polymorphism is a compromise between
efficiency and ease of development, use and
maintenance
Ask yourself: whose time is more important
– yours or the computer's?