Transcript slides

1
Chapter 10 - Object-Oriented
Programming:
Polymorphism
 2003 Prentice Hall, Inc. All rights reserved.
2
10.1 Introduction
• Polymorphism enables writing programs that
process objects in same class hierarchy as if all are
objects of their superclasses
• Key concept: subclass object can be treated as
superclass object
– “is-a” relationship
• However, a superclass object is not a subclass
object
 2003 Prentice Hall, Inc. All rights reserved.
3
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
• You can:
– Assign a superclass reference to superclass-type variable
– Assign a subclass reference to a subclass-type variable
– Assign a subclass reference to a superclass variable
• “is a” relationship
 2003 Prentice Hall, Inc. All rights reserved.
4
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.
5
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.
6
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.
7
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.
8
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
9
Outline
HierarchyRelati
onshipTest3.jav
a
 2003 Prentice Hall, Inc.
All rights reserved.
10
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
 2003 Prentice Hall, Inc. All rights reserved.
11
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.
12
10.4 Abstract Classes and Methods
• Abstract classes
– Used only as superclasses in inheritance hierarchies
– Its purpose is to provide an appropriate superclass from
which other classes can inherit
– Specify only what is common among subclasses
– Cannot be instantiated
– Incomplete
• subclasses fill in "missing pieces“
– Abstract classes can constitute several levels of the hierarchy
• Concrete classes
– Can be used to instantiate objects
– Implement every method they declare
– Provide specifics
 2003 Prentice Hall, Inc. All rights reserved.
13
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.
14
Using Polymorphism
• Required: a drawing program to display different
shapes, including new shape types added after writing
the drawing program
• Circle, Triangle, Rectangle and other new
shapes derive from an abstract superclass Shape
• In Shape an abstract draw method is declared.
• To draw any object, drawing program uses a Shape
variable containing a reference to the subclass object
to invoke the object’s draw method.
 2003 Prentice Hall, Inc. All rights reserved.
15
10.5 Case Study: Inheriting Interface and
Implementation
• Make abstract superclass Shape
– Declares the “interface” to the class hierarchy : The set of
methods that a program can invoke on all Shape objects
– Abstract method (must be implemented)
• getName
• 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.
16
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.
17
10.6 Case Study: Inheriting Interface and
Implementation
getArea
getVolume
getName
print
Shape
0.0
0.0
abstract
default
Object
implementatio
n
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.
18
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
19
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
20
// return x from coordinate pair
public int getX()
{
return x;
}
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.
21
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.
22
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.
23
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.
24
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.
25
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.
26
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.
27
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.
28
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.
29
 2003 Prentice Hall, Inc. All rights reserved.