1 Interfaces & Polymorphism part 2: Collections, Comparators, and More fun with Java graphics.
Java Programming: From the Ground Up Chapter 13: Polymorphism.
-
Upload
beverly-wilson -
Category
Documents
-
view
225 -
download
0
Transcript of Java Programming: From the Ground Up Chapter 13: Polymorphism.
![Page 1: Java Programming: From the Ground Up Chapter 13: Polymorphism.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/1.jpg)
Java Programming:From the Ground Up
Chapter 13:Polymorphism
![Page 2: Java Programming: From the Ground Up Chapter 13: Polymorphism.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/2.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/3.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/4.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/5.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/6.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/7.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/8.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/9.jpg)
The Shape Hierarchy
The Shape hierarchy
![Page 10: Java Programming: From the Ground Up Chapter 13: Polymorphism.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/10.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/11.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/12.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/13.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/14.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/15.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/16.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/17.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/18.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/19.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/20.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/21.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/22.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/23.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/24.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/25.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/26.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/27.jpg)
• 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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/28.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/29.jpg)
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.](https://reader035.fdocuments.in/reader035/viewer/2022062217/56649f1f5503460f94c36ae2/html5/thumbnails/30.jpg)
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.