Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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.