250 likes | 407 Views
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
E N D
Engr 691Special Topics in Engineering ScienceSoftware ArchitectureSpring Semester 2004Lecture 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 << integer; stream << char; stream << char *; stream << double; stream << 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 pre- and 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?