Chapter 10 - Object-Oriented Programming: Polymorphism Outline 10.1 Introduction 10.2 Relationships Among Objects in an Inheritance Hierarchy 10.2.1 Invoking Superclass Methods from Subclass Objects 10.2.2 Using Superclass References.

Download Report

Transcript Chapter 10 - Object-Oriented Programming: Polymorphism Outline 10.1 Introduction 10.2 Relationships Among Objects in an Inheritance Hierarchy 10.2.1 Invoking Superclass Methods from Subclass Objects 10.2.2 Using Superclass References.

Chapter 10 - Object-Oriented
Programming: Polymorphism
Outline
10.1
Introduction
10.2
Relationships Among Objects in an Inheritance Hierarchy
10.2.1 Invoking Superclass Methods from Subclass Objects
10.2.2 Using Superclass References with Subclass-Type
Variables
10.2.3 Subclass Method Calls via Superclass-Type Variables
10.3
Polymorphism Examples
10.4
Abstract Classes and Methods
10.5
Case Study: Inheriting Interface and Implementation
10.6
final Methods and Classes
10.7
Case Study: Payroll System Using Polymorphism
 2003 Prentice Hall, Inc. All rights reserved.
1
Chapter 10 - Object-Oriented
Programming: Polymorphism
Outline
10.8
10.9
10.10
10.11
10.12
Case Study: Creating and Using Interfaces
Nested Classes
Type-Wrapper Classes for Primitive Types
(Optional Case Study) Thinking About Objects: Incorporating
Inheritance into the Elevator Simulation
(Optional) Discovering Design Patterns: Introducing Creational,
Structural and Behavioral Design Patterns
10.12.1 Creational Design Patterns
10.12.2 Structural Design Patterns
10.12.3 Behavioral Design Patterns
10.12.4 Conclusion
10.12.5 Internet and World-Wide-Web Resources
 2003 Prentice Hall, Inc. All rights reserved.
2
3
10.1 Introduction
• Polymorphism
– “Program in the general”
– Treat objects in same class hierarchy as if all superclass
– Abstract class
• Common functionality
– Makes programs extensible
• New classes added easily, can still be processed
• In our examples
– Use abstract superclass Shape
• Defines common interface (functionality)
• Point, Circle and Cylinder inherit from Shape
– Class Employee for a natural example
 2003 Prentice Hall, Inc. All rights reserved.
4
10.2 Relationships Among Objects in an
Inheritance Hierarchy
• Previously (Section 9.4),
– Circle inherited from Point
– Manipulated Point and Circle objects using references
to invoke methods
• This section
– Invoking superclass methods from subclass objects
– Using superclass references with subclass-type variables
– Subclass method calls via superclass-type variables
• Key concept
– subclass object can be treated as superclass object
• “is-a” relationship
• superclass is not a subclass object
 2003 Prentice Hall, Inc. All rights reserved.
5
10.2.1 Invoking Superclass Methods from
Subclass Objects
• Store references to superclass and subclass objects
– Assign a superclass reference to superclass-type variable
– Assign a subclass reference to a subclass-type variable
• Both straightforward
– Assign a subclass reference to a superclass variable
• “is a” relationship
 2003 Prentice Hall, Inc. All rights reserved.
6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Outline
// Fig. 10.1: HierarchyRelationshipTest1.java
// Assigning superclass and subclass references to superclass- and
// subclass-type variables.
import javax.swing.JOptionPane;
HierarchyRelation
shipTest1.java
public class HierarchyRelationshipTest1 {
public static void main( String[] args )
{
// assign superclass reference to superclass-type variable
Assign superclass
Point3 point = new Point3( 30, 50 );
Line 11
Assign superclass
reference to superclassreference
type variable
to superclass-type variable
// assign subclass reference to subclass-type variable
Circle4 circle = new Circle4( 120, 89, 2.7 );
Line 14
Assign subclass reference
to reference
Assign subclass
subclass-type variable
to subclass-type variable
// invoke toString on superclass object using superclass variable
String output = "Call Point3's toString with superclass" +
" reference to superclass object: \n" + point.toString();
// invoke toString on subclass object using subclass variable
output += "\n\nCall Circle4's toString with subclass" +
" reference to subclass object: \n" + circle.toString();
InvokeLine
toString
on
17
Invoke
toString
superclass
object
using on
superclass
object using
superclass
variable
superclass variable
Invoke toString on
subclass
object
Line
22 using
Invoke
toString on
subclass
variable
subclass object using
subclass variable
 2003 Prentice Hall, Inc.
All rights reserved.
7
24
25
26
27
28
29
30
31
32
33
34
35
// invoke toString on subclass objectAssign
using subclass
superclass
variableto
reference
Point3 pointRef = circle;
superclass-type variable
output += "\n\nCall Circle4's toString with superclass" +
" reference to subclass object: \n" + pointRef.toString();
JOptionPane.showMessageDialog( null, output );
// display output
Outline
Invoke toString on
subclass
object using
HierarchyRelati
superclass
variable
onshipTest1.jav
a
System.exit( 0 );
} // end main
} // end class HierarchyRelationshipTest1
Line 25
Assign subclass
reference to
superclass-type
variable.
Line 27
Invoke toString on
subclass object using
superclass variable.
 2003 Prentice Hall, Inc.
All rights reserved.
8
10.2.2 Using Superclass References with
Subclass-Type Variables
• Previous example
– Assigned subclass reference to superclass-type variable
• Circle “is a” Point
• Assign superclass reference to subclass-type
variable
– Compiler error
• No “is a” relationship
• Point is not a Circle
• Circle has data/methods that Point does not
– setRadius (declared in Circle) not declared in
Point
– Cast superclass references to subclass references
• Called downcasting
• Invoke subclass functionality
 2003 Prentice Hall, Inc. All rights reserved.
9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Fig. 10.2: HierarchyRelationshipTest2.java
// Attempt to assign a superclass reference to a subclass-type variable.
public class HierarchyRelationshipTest2 {
public static void main( String[] args )
{
Point3 point = new Point3( 30, 50 );
Circle4 circle; // subclass-type variable
// assign superclass reference to subclass-type variable
circle = point; // Error: a Point3 is not a Circle4
}
} // end class HierarchyRelationshipTest2
Assigning superclass reference
to subclass-type variable causes
compiler error
Outline
HierarchyRelati
onshipTest2.jav
a
Line 12
Assigning superclass
reference to subclasstype variable causes
compiler error.
HierarchyRelationshipTest2.java:12: incompatible types
found
: Point3
required: Circle4
circle = point; // Error: a Point3 is not a Circle4
^
1 error
 2003 Prentice Hall, Inc.
All rights reserved.
10
10.2.3 Subclass Method Calls via
Superclass-Type variables
• Call a subclass method with superclass reference
– Compiler error
• Subclass methods are not superclass methods
 2003 Prentice Hall, Inc. All rights reserved.
11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fig. 10.3: HierarchyRelationshipTest3.java
// Attempting to invoke subclass-only member methods through
// a superclass reference.
public class HierarchyRelationshipTest3 {
Outline
HierarchyRelati
onshipTest3.jav
a
public static void main( String[] args )
{
Point3 point;
Circle4 circle = new Circle4( 120, 89, 2.7 );
point = circle;
// aim superclass reference at subclass object
// invoke superclass (Point3) methods on subclass
// (Circle4) object through superclass reference
int x = point.getX();
int y = point.getY();
point.setX( 10 );
point.setY( 20 );
point.toString();
 2003 Prentice Hall, Inc.
All rights reserved.
12
22
23
24
25
26
27
28
29
30
31
32
// attempt to invoke subclass-only (Circle4) methods on
// subclass object through superclass (Point3) reference
double radius = point.getRadius();
point.setRadius( 33.33 );
double diameter = point.getDiameter();
double circumference = point.getCircumference();
double area = point.getArea();
} // end main
} // end class HierarchyRelationshipTest3
Attempt to invoke subclassonly (Circle4) methods on
subclass object through
superclass (Point3)
reference.
Outline
HierarchyRelati
onshipTest3.jav
a
Lines 24-28
Attempt to invoke
subclass-only
(Circle4) methods
on subclass object
through superclass
(Point3) reference.
 2003 Prentice Hall, Inc.
All rights reserved.
HierarchyRelationshipTest3.java:24: cannot resolve symbol
symbol : method getRadius ()
location: class Point3
double radius = point.getRadius();
^
HierarchyRelationshipTest3.java:25: cannot resolve symbol
symbol : method setRadius (double)
location: class Point3
point.setRadius( 33.33 );
^
HierarchyRelationshipTest3.java:26: cannot resolve symbol
symbol : method getDiameter ()
location: class Point3
double diameter = point.getDiameter();
^
HierarchyRelationshipTest3.java:27: cannot resolve symbol
symbol : method getCircumference ()
location: class Point3
double circumference = point.getCircumference();
^
HierarchyRelationshipTest3.java:28: cannot resolve symbol
symbol : method getArea ()
location: class Point3
double area = point.getArea();
^
5 errors
13
Outline
HierarchyRelati
onshipTest3.jav
a
 2003 Prentice Hall, Inc.
All rights reserved.
14
10.3 Polymorphism Examples
• Examples
– Suppose Rectangle derives from Quadrilateral
• Rectangle more specific than Quadrilateral
• Any operation on Quadrilateral can be done on
Rectangle (i.e., perimeter, area)
• Suppose designing video game
– Superclass SpaceObject
• Subclasses Martian, SpaceShip, LaserBeam
• Contains method draw
– To refresh screen
• Send draw message to each object
• Same message has “many forms” of results
 2003 Prentice Hall, Inc. All rights reserved.
15
10.3 Polymorphism Examples
• Video game example, continued
– Easy to add class Mercurian
• Extends SpaceObject
• Provides its own implementation of draw
– Programmer does not need to change code
• Calls draw regardless of object’s type
• Mercurian objects “plug right in”
 2003 Prentice Hall, Inc. All rights reserved.
16
10.4 Abstract Classes and Methods
• Abstract classes
– Are superclasses (called abstract superclasses)
– Cannot be instantiated
– Incomplete
• subclasses fill in "missing pieces"
• Concrete classes
– Can be instantiated
– Implement every method they declare
– Provide specifics
 2003 Prentice Hall, Inc. All rights reserved.
17
10.4 Abstract Classes and Methods (Cont.)
• Abstract classes not required, but reduce client
code dependencies
• To make a class abstract
– Declare with keyword abstract
– Contain one or more abstract methods
public abstract void draw();
– Abstract methods
• No implementation, must be overridden
 2003 Prentice Hall, Inc. All rights reserved.
18
10.4 Abstract Classes and Methods (Cont.)
• Application example
– Abstract class Shape
• Declares draw as abstract method
– Circle, Triangle, Rectangle extends Shape
• Each must implement draw
– Each object can draw itself
• Iterators
– Array, ArrayList (Chapter 22)
– Walk through list elements
– Used in polymorphic programming to traverse a collection
 2003 Prentice Hall, Inc. All rights reserved.
19
10.5 Case Study: Inheriting Interface and
Implementation
• Make abstract superclass Shape
– Abstract method (must be implemented)
• getName, print
• Default implementation does not make sense
– Methods may be overridden
• getArea, getVolume
– Default implementations return 0.0
• If not overridden, uses superclass default implementation
– Subclasses Point, Circle, Cylinder
 2003 Prentice Hall, Inc. All rights reserved.
20
10.5 Case Study: Inheriting Interface and
Implementation
Shape
Point
Circle
Cylinder
Fig. 10.4 Shape hierarchy class diagram.
 2003 Prentice Hall, Inc. All rights reserved.
21
10.6 Case Study: Inheriting Interface and
Implementation
getArea
getVolume
getName
print
Shape
0.0
0.0
= 0
= 0
Point
0.0
0.0
"Point"
[x,y]
Circle
pr2
0.0
"Circle"
center=[x,y];
radius=r
2pr2 +2prh
pr2h
"Cylinder"
center=[x,y];
radius=r;
height=h
Cylinder
Fig. 10.5 Polimorphic interface for the Shape hierarchy classes.
 2003 Prentice Hall, Inc. All rights reserved.
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Outline
// Fig. 10.6: Shape.java
// Shape abstract-superclass declaration.
Shape.java
public abstract class Shape extends Object {
// return area of shape; 0.0 by default
public double getArea()
Keyword abstract
{
declares class Shape
return 0.0;
abstract class
}
as
// return volume of shape; 0.0 by default
public double getVolume()
{
return 0.0;
}
Line 4
Keyword abstract
declares class Shape
as abstract class
Line 19
Keyword abstract
declares method
getName as abstract
method
// abstract method, overridden by subclasses
public abstract String getName();
} // end abstract class Shape
Keyword abstract declares
method getName as abstract
method
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 10.7: Point.java
// Point class declaration inherits from Shape.
public class Point extends Shape {
private int x; // x part of coordinate pair
private int y; // y part of coordinate pair
23
Outline
Point.java
// no-argument constructor; x and y default to 0
public Point()
{
// implicit call to Object constructor occurs here
}
// constructor
public Point( int xValue, int yValue )
{
// implicit call to Object constructor occurs here
x = xValue; // no need for validation
y = yValue; // no need for validation
}
// set x in coordinate pair
public void setX( int xValue )
{
x = xValue; // no need for validation
}
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// return x from coordinate pair
public int getX()
{
return x;
}
24
Outline
Point.java
// set y in coordinate pair
public void setY( int yValue )
{
y = yValue; // no need for validation
}
// return y from coordinate pair
public int getY()
{
return y;
}
Lines 47-50
Override abstract
method getName.
Override
abstract
method getName.
// override abstract method getName to return "Point"
public String getName()
{
return "Point";
}
// override toString to return String representation of Point
public String toString()
{
return "[" + getX() + ", " + getY() + "]";
}
} // end class Point
 2003 Prentice Hall, Inc.
All rights reserved.
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 10.8: Circle.java
// Circle class inherits from Point.
public class Circle extends Point {
private double radius; // Circle's radius
Outline
Circle.java
// no-argument constructor; radius defaults to 0.0
public Circle()
{
// implicit call to Point constructor occurs here
}
// constructor
public Circle( int x, int y, double radiusValue )
{
super( x, y ); // call Point constructor
setRadius( radiusValue );
}
// set radius
public void setRadius( double radiusValue )
{
radius = ( radiusValue < 0.0 ? 0.0 : radiusValue );
}
 2003 Prentice Hall, Inc.
All rights reserved.
26
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// return radius
public double getRadius()
{
return radius;
}
// calculate and return diameter
public double getDiameter()
{
return 2 * getRadius();
}
Outline
Circle.java
Lines 45-48
Override method
getArea to return
circle area.
// calculate and return circumference
Override method
public double getCircumference()
getArea to
{
return circle area
return Math.PI * getDiameter();
}
// override method getArea to return Circle area
public double getArea()
{
return Math.PI * getRadius() * getRadius();
}
 2003 Prentice Hall, Inc.
All rights reserved.
27
50
51
52
53
54
55
56
57
58
59
60
61
62
// override abstract method getName to return "Circle"
public String getName()
Override
{
return "Circle";
abstract
}
method getName
// override toString to return String representation of Circle
public String toString()
{
return "Center = " + super.toString() + "; Radius = " + getRadius();
}
Outline
Circle.java
Lines 51-54
Override abstract
method getName.
} // end class Circle
 2003 Prentice Hall, Inc.
All rights reserved.
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 10.9: Cylinder.java
// Cylinder class inherits from Circle.
public class Cylinder extends Circle {
private double height; // Cylinder's height
Outline
Cylinder.java
// no-argument constructor; height defaults to 0.0
public Cylinder()
{
// implicit call to Circle constructor occurs here
}
// constructor
public Cylinder( int x, int y, double radius, double heightValue )
{
super( x, y, radius ); // call Circle constructor
setHeight( heightValue );
}
// set Cylinder's height
public void setHeight( double heightValue )
{
height = ( heightValue < 0.0 ? 0.0 : heightValue );
}
 2003 Prentice Hall, Inc.
All rights reserved.
29
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// get Cylinder's height
public double getHeight()
{
return height;
}
Override method
getArea to
return cylinder
area
// override abstract method getArea to Override
return Cylinder
method area
public double getArea()
getVolume to
{
return cylinder
return 2 * super.getArea() + getCircumference() * getHeight();
volume
}
// override abstract method getVolume to return Cylinder volume
public double getVolume()
{
return super.getArea() * getHeight();
}
// override abstract method getName to return "Cylinder"
public String getName()
Override
{
abstract
return "Cylinder";
method getName
}
Outline
Cylinder.java
Lines 33-36
Override method
getArea to return
cylinder area
Lines 39-42
Override method
getVolume to return
cylinder volume
Lines 45-48
Override abstract
method getName
 2003 Prentice Hall, Inc.
All rights reserved.
30
49
50
51
52
53
54
55
56
Outline
// override toString to return String representation of Cylinder
public String toString()
{
return super.toString() + "; Height = " + getHeight();
}
Cylinder.java
} // end class Cylinder
 2003 Prentice Hall, Inc.
All rights reserved.
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 10.10: AbstractInheritanceTest.java
// Driver for shape, point, circle, cylinder hierarchy.
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
Outline
AbstractInherit
anceTest.java
public class AbstractInheritanceTest {
public static void main( String args[] )
{
// set floating-point number format
DecimalFormat twoDigits = new DecimalFormat( "0.00" );
// create Point, Circle and Cylinder objects
Point point = new Point( 7, 11 );
Circle circle = new Circle( 22, 8, 3.5 );
Cylinder cylinder = new Cylinder( 20, 30, 3.3, 10.75 );
// obtain name and string representation of each object
String output = point.getName() + ": " + point + "\n" +
circle.getName() + ": " + circle + "\n" +
cylinder.getName() + ": " + cylinder + "\n";
Shape arrayOfShapes[] = new Shape[ 3 ];
// create Shape array
 2003 Prentice Hall, Inc.
All rights reserved.
32
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// aim arrayOfShapes[ 0 ] at subclass Point object
arrayOfShapes[ 0 ] = point;
Outline
// aim arrayOfShapes[ 1 ] at subclass CircleCreate
objectan
arrayOfShapes[ 1 ] = circle;
array of
AbstractInherit
Loop
through
generic Shape objects
anceTest.java
arrayOfShapes to get
// aim arrayOfShapes[ 2 ] at subclass Cylinder object
name, string representation,
Lines 26-32
arrayOfShapes[ 2 ] = cylinder;
area and volume of Create
every an array of
shape in array
// loop through arrayOfShapes to get name, string
generic Shape
// representation, area and volume of every Shape in array
for ( int i = 0; i < arrayOfShapes.length; i++ ) {
output += "\n\n" + arrayOfShapes[ i ].getName() + ": " +
arrayOfShapes[ i ].toString() + "\nArea = " +
twoDigits.format( arrayOfShapes[ i ].getArea() ) +
"\nVolume = " +
twoDigits.format( arrayOfShapes[ i ].getVolume() );
}
JOptionPane.showMessageDialog( null, output );
System.exit( 0 );
// display output
objects
Lines 36-42
Loop through
arrayOfShapes to
get name, string
representation, area
and volume of every
shape in array
} // end main
} // end class AbstractInheritanceTest
 2003 Prentice Hall, Inc.
All rights reserved.
33
 2003 Prentice Hall, Inc. All rights reserved.