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).
Term used in several different ways in computer science
Polymorphism is a trivial issue in untyped languages
All variables are potentially polymorphic
Variables take on the 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
Variable declared as one class can hold values from subclass
A single function name denoting two or more function bodies is overloaded
+ means both integer and floating
addition
In Java, + also used for string concatenation
class Spouse
{ public void sendFlowersTo(Address anAddress)
{ go to florist;
give florist message sendFlowersTo(anAddress);
}
}
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);
}
}
}
sendFlowersTo methods are semantically
related but not related via inheritance
-- the number, types, and order of parameters
-- parametric overloading
Polymorphic Symbol << used for both left shift and
stream output -- latter also overloaded by type of value
stream << integer;
stream << char;
stream << char *;
stream << double;
stream << complex;
Overriding occurs when child class changes meaning of function from parent
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); }
}
class IncomparableMagnitudeException extends Exception
{ public IncomparableMagnitudeException() { }
public IncomparableMagnitudeException(String msg) { super(msg); }
}
To define all six comparisons in a noncircular manner, subclasses must:
Object method equals()
if default not appropriate
Magnitude method
lessThan() or lessOrEqual()
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
Semantics of abstract methods should be specified carefully -- e.g., using pre- and postconditions
Subclasses should adhere to specification
abstract modifier for 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)
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");
Message r.between(p,q) has the following trace of dynamic
binding:
between() in
Point, not found
between() in
Magnitude, found, binds call
Magnitude.between, checks for
lessOrEqual() in Point, not found
Magnitude.between, checks for
lessOrEqual() in Magnitude, found, binds
call
Magnitude.lessOrEqual, checks for
lessThan() in Point, found, binds call
Point.lessThan, returns false
since (0,0) is not less than (0,0)
Magnitude.lessOrEqual, checks for
equals() in Point, not found
Magnitude.lessOrEqual, checks for
equals() in Magnitude, not found
Magnitude.lessOrEqual, checks for
equals() in Object, found, binds call
Object.equals, returns true
Magnitude.lessOrEqual, returns true
since (0,0) <= (0,0)
Magnitude.between, returns true
since (0,0) <= (0,0) and (0,0) <= (10,10), l
C++ example:
template <class T> class Link
{
public:
...
private:
T value;
Link * nextLink;
}
Link<Shape> sl;
Declaration above makes s1 a Link variable
that has a value of type Shape
Keyword generic reserved
Experimental versions of Java do support generics
extends)
implements)
final prevents overriding
abstract for deferred methods, signature
but no body
UP to ENGR 691 Lecture Notes root document?