java programming: from the ground up chapter 13: polymorphism

30
Java Programming: From the Ground Up Chapter 13: Polymorphism

Upload: beverly-wilson

Post on 04-Jan-2016

225 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Java Programming: From the Ground Up Chapter 13: Polymorphism

Java Programming:From the Ground Up

Chapter 13:Polymorphism

Page 2: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism

• Polymorphism is the third fundamental concept of OOP.

• In contrast to inheritance, polymorphism underscores the differences of class behavior in an inheritance hierarchy.

Page 3: Java Programming: From the Ground Up Chapter 13: Polymorphism

Ad-hoc Polymorphism – Method Overloading

• The code segment overloads the constructor of a Song class.

• The constructor is polymorphic; the constructor has three forms.

1. public class Song2. {3. private String composer;4. private String lyricist;5.6. public Song () // default constructor7. {8. composer ="" ;9. lyricist = "";10. }11. public Song(String name) // same person wrote words and music12. {13. composer =name ;14. lyricist = name;15. }16. public Song (String name1, String name2) // two songwriters17. {18. composer =name1;19. lyricist = name2;20. }21. // other Song methods go here.......22. }

• Method overloading, a form of polymorphism, is also known as ad-hoc polymorphism.

Page 4: Java Programming: From the Ground Up Chapter 13: Polymorphism

Upcasting

• Upcasting in an inheritance hierarchy allows an object of a derived type to be considered an object of a base type.

Dog elvis;elvis = new HoundDog();

elvis = new Beagle();elvis = new Bassett();

 • Because a HoundDog is-a Dog, a HoundDog reference can be upcast to Dog (line 2).

• Similarly, a Beagle reference and a Bassett reference can also be considered Dog references (lines 3 and 4).

• The reference elvis is polymorphic, i.e., elvis has “many forms” and elvis can refer to a Dog object, a HoundDog object, a Beagle object, or a Bassett object.

Page 5: Java Programming: From the Ground Up Chapter 13: Polymorphism

Dynamic (or Late) Binding

• A third form of polymorphism, dynamic or late binding, accentuates the behavioral differences among objects of different classes in a hierarchy.

• This is in contrast to inheritance, which exploits the similarities of classes.

Page 6: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

• Each class of the Shape hierarchy encapsulates a different geometrical shape.

• Some typical shapes are:

******************** *****Square

%%%%%%%%%% %%%%%RightTriangle

# # # # # # # # # # # # # # #

Triangle

Page 7: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

Problem Statement:

• Design classes Square, RightTriangle, and Triangle that encapsulate three geometrical shapes. Each class should implement a method

void draw (int x, int y)

that “draws” a square, a right triangle, or an equilateral triangle (a triangle with three equal sides), respectively.

• The parameters x and y specify the relative position of the figure: y lines down and x spaces across from the current position of the screen cursor.

• The instance variables of each class are:

– int rows, the number of rows that comprise the figure,

and

– char character, the keyboard character used for drawing the figure.

Page 8: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

Java Solution:

• There is much the same about the three classes: the attributes are the same, and except for the draw(...) method, the getter and setter methods are the same.

• Factor out the commonality of the classes into one (abstract) superclass, Shape, which serves as a base class in an inheritance hierarchy that includes Square, RightTriangle, and Triangle.

Page 9: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

The Shape hierarchy

Page 10: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

• The abstract class Shape has the following form:

1. public abstract class Shape 2. {3. protected int rows; // figure drawn on rows rows4. protected char character; // the drawing character5.  6. public Shape()7. {8. rows = 0;9. char character = ' ';10. }11.  12. public Shape(int x, char ch)13. {14. rows = x;15. character = ch;16. }17.  18. public int getRows()19. {20. return rows;21. }22.  23. public char getCharacter()24. {25. return character;26. }27.  28. public void setRows(int y)29. {30. rows = y;31. }32.  33. public void setCharacter(char ch)34. {35. character = ch;36. }37.  38. public abstract void draw(int x, int y); // must be implemented in concrete subclasses39.  40. }

Page 11: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

public class Square extends Shape{public Square(){ // call Shape default constructor super(); }public Square(int x, char ch){ // call Shape 2 argument constr. super(x,ch);} public void draw(int x, int y) { // move down y lines for ( int i = 1; i <= y; i++) System.out.println(); // for each row for (int len = 1; len<= rows;len++) { // indent x spaces for (int i = 1; i <= x; i++) System.out.print(' '); for(int j = 1; j <=rows; j++) System.out.print(character); System.out.println(); } }}

public class RightTriangle extends Shape{public RightTriangle(){ // call Shape default constructor super();}public RightTriangle(int x, char ch){ // call Shape 2 argument constr.

super(x,ch);}public void draw(int x, int y) { // move down y lines for ( int i = 1; i <= y; i++) System.out.println();

// for each row for (int len = 1; len<= rows; len++) { //indent x spaces for (int i = 1; i <= x; i++) System.out.print(' '); for (int j = 1; j <= len; j++) System.out.print(character); System.out.println(); } }}

public class Triangle extends Shape{public Triangle (){ // call Shape default constructor super();}public Triangle (int x, char ch){ // call Shape 2 argument constr.

super(x,ch);}public void draw(int x, int y){ // move down y lines for ( int i = 1; i <= y; i++) System.out.println();

// for each row for(int len=1; len<=rows; len++) { //indent; the vertex is centered for(int i=0; i <= rows-len+x; i++) System.out.print(" "); for(int i =1; i<=len; i++) System.out.print(character +" " ); System.out.println(); } }}

Page 12: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

Problem Statement:

• Devise a test class that interactively queries a user for one of three shapes and subsequently draws the requested shape.

Java Solution:

• The main(...) method of the following test class, requests input 1, 2, or 3 representing a square, a right triangle or an equilateral triangle, respectively.

• Because a Square is-a Shape, a RightTriangle is-a Shape, and a Triangle is-a Shape, all references are upcast to Shape

Page 13: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

1. import java.util.*;2. public class TestDraw3. {4. public static void main(String[] args)5. {6. Scanner input = new Scanner(System.in);7. Shape shape = null; // all references can be upcast to Shape8. int shapeNumber; //code number for each type of figure9. System.out.print("Enter 1: Square, 2: RightTriangle, 3: Equilateral Triangle: ");10. shapeNumber = input.nextInt();11.  12. switch (shapeNumber)13. {14. case 1 : shape = new Square(4,'*'); //size 4, draw with *15. break;16. case 2 : shape = new RightTriangle(5,'#'); //size 5, draw with #17. break;18. case 3 : shape = new Triangle(6,'+'); //size 6, draw with +19. break;20. default : System.out.println("Invalid entry"); // shapeNumber is not 1,2, or 321. System.exit(0); // bad data, terminate the application22. }23. shape.draw(1,1);24. }25. }

Page 14: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

Discussion:

• The application runs as you might expect, but only because Java implements polymorphism through late binding.

• On line 22, it appears that a Shape object (shape) invokes its draw(…) method.

• Shape is an abstract class, so no Shape object can exist.

• Shape does not implement draw(...) as part of the Shape class, draw(...) is declared abstract.

 • Which draw(...) method is invoked?  

– The reference variable shape could refer to– a Square object (line 13), – a RightTriangle object (line 15), or– a Triangle object (line 17).

Page 15: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Shape Hierarchy

• When TestDraw is compiled and translated into bytecode, the Java compiler cannot determine which draw(…) method is applicable.

• The compiler knows that shape refers to a kind of Shape, but it does not know which kind.

• The appropriate draw(...) method is not discernible until the program runs and the user chooses one of three shapes.

• Consequently, the compiled version of the program, i.e., the bytecode that executes on the Java Virtual Machine, does not specify which draw(...) method is appropriate.

• The choice of the correct draw(...) method is postponed until the program executes; that is, the choice is postponed until runtime.

• Polymorphism via dynamic or late binding refers to choosing the appropriate method not at compile time, but at runtime.

• When the TestDraw application runs, Java determines which form of draw(...) to execute.

Page 16: Java Programming: From the Ground Up Chapter 13: Polymorphism

How Dynamic Binding Works

• The reference variable shape is declared to be of type Shape:

Shape shape

• Shape is the apparent type or declared type of shape.

• A Shape object cannot be instantiated because Shape is an abstract class.

• The variable shape can refer to a Square object or a Triangle object, or an object of any concrete class that extends Shape.

Page 17: Java Programming: From the Ground Up Chapter 13: Polymorphism

How Dynamic Binding Works

• The real type or actual type of a reference variable is the type of the object that is created by the new operation.

• The real type of shape is Square, RightTriangle, or Triangle, depending on user input.

• Assume that the user, TestDraw, chooses to draw a right triangle.

• In this case, the real type of shape is RightTriangle.

• When the draw(...) method is invoked by shape, Java begins searching for a fully implemented draw(...) method.

• The search begins in the RightTriangle class (the real type of shape).

• If the RightTriangle class has implemented a draw(...) method then the search ends, and that method is called.

• If not, then Java searches the parent of RightTriangle.

• Searching continues all the way up the hierarchy until an implemented draw(...) method is found (or until the Object class is reached).

• Java uses late binding for all method invocations except final, private, and static methods.

Page 18: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism Makes Programs Extensible

• Polymorphism allows you to generalize your classes with ease.

Problem Statement:

• Expand the Shape class with a subclass, EmptySquare, that implements a draw method, which produces a square that is not filled.

****** ** ** ******

Page 19: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism Makes Programs Extensible

Java Solution: 1. class EmptySquare extends Shape2. {3. public EmptySquare()4. {5. super(); // calls default Shape constructor 6. }7.  8. public EmptySquare(int x, char ch)9. {10. super(x,ch); // call 2-argument Shape constructor11. }12.  13. public void draw(int x, int y)14. {15. // move down y lines16. for ( int i = 1; i <= y; i++)17. System.out.println();

18. // for each row 19. for (int len = 1; len<= rows; len++)20. {21. // indent x spaces22. for (int i = 1; i <= x; i++)23. System.out.print(' ');24.  25. // print a character on an edge26. // print spaces in the interior27.  28. for(int j = 1; j <=rows; j++)29. if (j ==1|| j==rows || len==rows || len == 1 ) // on edge30. System.out.print(character);31. else32. System.out.print(" ");33. System.out.println();34. }35. }36. }

Page 20: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism and the Object class

• Most horror films have tag lines – catchphrases such as “Frankenstein: A Monster Science Created - But Could Not Destroy!”

Problem Statement:

• Design an application that stores Movie objects (a film title and a tag line) in an array, andallows Holly to search the array and retrieve a film’s tag line, given the title of the film.

 Java Solution:

• In addition to the two attributes, title and tagLine, the following Movie class:

– implements the standard getter and setter methods,

– overrides the toString() method inherited from Object so that the toString() version of the Movie class returns the title and the tag line as a String,

– overrides the equals(...) method inherited from Object implementing an equality that is based on the title of a film, so that two Movie objects with the same title are equal, and

– implements the Comparable interface by alphabetically comparing titles so that the array of Movie objects can be sorted by title.

Page 21: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism and the Object class

Movie overrides equals(Object o) and toString(); Movie implements Comparable

Page 22: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism and the Object class

1. public class Movie implements Comparable2. {3. private String title;4. private String tagLine;5.  6. public Movie()7. // default constructor, makes an empty Movie object8. {9. title = "";10. tagLine = "";11. }12.  13. public Movie( String name, String tag)14. {15. // two-argument constructor, creates a Movie object with a title and tag line16. title = name;17. tagLine = tag;18. }19.  20. public boolean equals(Object o)21. // override the equals object inherited from Object22. // two Movie objects are equal if they have the same title23. {24. return title.equals(((Movie)o).title); //notice that o must be cast to Movie25. }26.  27. public int compareTo(Object o)28. // implement compareTo from the Comparable interface29. // compareTo compares two titles. The compareTo from String is invoked30. {31. return title.compareTo(((Movie)o).title); // compares two Strings32. }33.  34.

35. public String toString()36. // overwrites toString() from Object37. {38. return "Title: "+title+" Tag line: "+ tagLine;39. }40.  41. public void setTitle(String title)42. {43. this.title = title;44. }45.  46. public String getTitle()47. {48. return title;49. }50.  51. public void setTagLine(String tagLine)52. {53. this. tagLine = tagLine;54. }55.  56. public String getTagLine ()57. {58. return tagLine;59. }60. }

Page 23: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism and the Object class

• To locate a particular movie, the application utilizes the binary search algorithm.

• Binary search utilizes a sorted array.

• Because Movie implements the Comparable interface, an array of Movie references can be ordered.

• In the implementation of binary search e, the array parameter x and the key parameter are both declared of type Object.

• Thus, the method call,

search(Object[] x, Object key)

can pass arguments of any class.

Page 24: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism and the Object class

1. public class Search2. {3. public static int search(Object [] x, Object key, int size)4. {5. // binary search from Chapter 76. int lo = 0;7. int hi = size -1;8. int mid = (lo+hi)/2;9. while ( lo <= hi)10. {11. if (key.equals(x[mid])) // key found12. return mid;13. else if (((Comparable)key).compareTo(x[mid]) < 0) 14. hi = mid -1;15. else16. lo = mid + 1;17. mid = (lo+hi)/2;18. }19. return -1; // key not found20. }21. }

• The cast on line 13: 

else if (((Comparable)key).compareTo(x[mid]) < 0)

is necessary because the parameter key refers to an Object, and Object does not implement Comparable.

• Without the downcast, the compiler issues a message to the effect that the name compareTo is unknown.

Page 25: Java Programming: From the Ground Up Chapter 13: Polymorphism

Polymorphism and the Object class

1. import java.util.Scanner;2. import java.io.*;3.  4. public class MovieSearch5. {6. Scanner input = new Scanner(System.in);7. private String title, tagLine;8. private Movie[] movies ;9. private final int MAX_MOVIES = 500;10. private int num; // the total number of films in the file

11. public MovieSearch() throws IOException12. {13. num = 0;14. movies = new Movie[MAX_MOVIES];15. File inputFile = new File("movielines.txt");16. if( !inputFile.exists())17. {18. System.out.println("File movielines.txt not found ");19. System.exit(0);20. }21. Scanner input = new Scanner(inputFile);22. String line; // to hold one full line from the file23. while (input.hasNext()) // while there is more data24. {25. String name = input.nextLine(); // advance to next line, returns all “skipped”

data26. String tag = input.nextLine();27. movies[num] = new Movie (name, tag);28. num++;29. }30.  31. input.close();32. SelectionSort.sort(movies, num); // the array must be kept sorted to utilize binary search33. System.out.println("\n"+ num +" titles entered");34. System.out.println("-------------------\n");35. searchFilm();36. }

37. public void searchFilm()38. {39. // Prompt user for a movie title40. // Search the array for the film with that title41. // If the film is in the array, print the title and tagline42. // If the film is not in the array, issue a message

43. System.out.println();44. Movie key = new Movie(); // an empty Movie object45. int place; // a position in the array46. System.out.println("Input a title. Hit Enter to end");47. do48. { //get title from user49. System.out.print("\nTitle: ");50. title = input.nextLine();51. if (title.equals(""))52. break; // end if user hits 'Enter'53. key.setTitle(title); // wrap title in a Movie object54. key.setTagLine(""); //the tagline is empty at this point55.  56. // invoke binary search to find a movie object with the title as key57. // if successful, place contains the position in the array; otherwise58. // place contains -159. place = Search.search(movies, key, num); // key is a Movie object60.  61. if (place >= 0 && place < num) // successful search62. System.out.println(movies[place]); // print the object at place63. else64. System.out.println(title +" not found");65. } while(true);66. }67.  68. public static void main(String[] args) throws IOException69. {70. MovieSearch movieSearch = new MovieSearch();71. }72. }

Page 26: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Movie Class

Discussion

The Movie Class:

• On line 21 of the Movie class

return title.equals(((Movie)x).title); 

the equals(...) method invoked on line 21 is called by title, which is a String.

• The String class overrides equals(Object). So the call

title.equals(((Movie)x).title); 

compares two String objects via String's version of equals(...), i.e., by comparing the characters in each String.

• The cast of x to Movie is necessary because the apparent type of x is Object and Objects do not have title attributes.

Page 27: Java Programming: From the Ground Up Chapter 13: Polymorphism

• Similarly, the statement

return title.compareTo(((Movie)x).title);

invokes the compareTo(...) method of the String class.

• The remainder of the Movie class is straightforward and should present no difficulty.

Page 28: Java Programming: From the Ground Up Chapter 13: Polymorphism

The Search Class

The Search Class:

• On line 11 of the Search class,   if (key.equals(x[mid]))

the key object is compared to x[mid] via equals(...).

• This is the equals(...) method inherited from Object.

• If this equals(...) method is not overridden in Movie, then references are compared, and the result is incorrect.

• Similarly, on line 13,

else if (((Comparable)key).compareTo(x[mid]) < 0)

the compareTo(...) method is invoked by key.

• Accordingly, Movie implements the Comparable interface.

Page 29: Java Programming: From the Ground Up Chapter 13: Polymorphism

The MovieSearch Class

The MovieSearch Class:

• The statements on lines 22-28 continually perform the following actions:

– read a title and tagline from the text file, movielines.txt,

– instantiate a Movie object with the two-argument constructor, and

– store a reference to the Movie object in the array movies,

until all data has been read from movielines.txt.

Page 30: Java Programming: From the Ground Up Chapter 13: Polymorphism

The MovieSearch Class

• The searchFilm() method repeatedly

– creates an empty Movie object, key (line 42),

– queries a user for the title of a movie,

– sets the title attribute of key appropriately and sets the tagline field to the empty string

– passes key to search(...), which returns the index of key in the array movies, and

– processes the returned information from search(...):

• If key is not found, search(...) returns –1.

• If key is found, the film and tagline are displayed, otherwise a “title not found” message is issued.

until a user presses “Enter” without supplying a movie title.