Presentation is loading. Please wait.

Presentation is loading. Please wait.

Java Programming: From the Ground Up

Similar presentations


Presentation on theme: "Java Programming: From the Ground Up"— Presentation transcript:

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

2 Polymorphism Polymorphism is the third fundamental concept of OOP.
In contrast to inheritance, polymorphism underscores the differences of class behavior in an inheritance hierarchy.

3 Ad-hoc Polymorphism – Method Overloading
The code segment overloads the constructor of a Song class. The constructor is polymorphic; the constructor has three forms. public class Song { private String composer; private String lyricist; public Song () // default constructor composer ="" ; lyricist = ""; } public Song(String name) // same person wrote words and music composer =name ; lyricist = name; public Song (String name1, String name2) // two songwriters composer =name1; lyricist = name2; // other Song methods go here Method overloading, a form of polymorphism, is also known as ad-hoc polymorphism.

4 elvis = new HoundDog();
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.

5 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.

6 The Shape Hierarchy Each class of the Shape hierarchy encapsulates a different geometrical shape. Some typical shapes are: ***** Square % %% %%% %%%% %%%%% RightTriangle # # # # # # # # # # # # # # # Triangle

7 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.

8 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.

9 The Shape Hierarchy The Shape hierarchy

10 The Shape Hierarchy The abstract class Shape has the following form:
public abstract class Shape { protected int rows; // figure drawn on rows rows protected char character; // the drawing character public Shape() rows = 0; char character = ' '; } public Shape(int x, char ch) rows = x; character = ch; public int getRows() return rows; public char getCharacter() return character; public void setRows(int y) rows = y; public void setCharacter(char ch) public abstract void draw(int x, int y); // must be implemented in concrete subclasses

11 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() public RightTriangle(int x, char ch) // call Shape 2 argument constr. // 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 j = 1; j <= len; j++) System.out.print(character); public class Triangle extends Shape public Triangle () public Triangle (int x, char ch) 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 +" " ); } }

12 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

13 The Shape Hierarchy import java.util.*; public class TestDraw {
public static void main(String[] args) Scanner input = new Scanner(System.in); Shape shape = null; // all references can be upcast to Shape int shapeNumber; //code number for each type of figure System.out.print("Enter 1: Square, 2: RightTriangle, 3: Equilateral Triangle: "); shapeNumber = input.nextInt(); switch (shapeNumber) case 1 : shape = new Square(4,'*'); //size 4, draw with * break; case 2 : shape = new RightTriangle(5,'#'); //size 5, draw with # case 3 : shape = new Triangle(6,'+'); //size 6, draw with + default : System.out.println("Invalid entry"); // shapeNumber is not 1,2, or 3 System.exit(0); // bad data, terminate the application } shape.draw(1,1);

14 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).

15 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.

16 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.

17 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.

18 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. ***** * * * * * * *****

19 Polymorphism Makes Programs Extensible
Java Solution: class EmptySquare extends Shape { public EmptySquare() super(); // calls default Shape constructor } public EmptySquare(int x, char ch) super(x,ch); // call 2-argument Shape constructor 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(' '); // print a character on an edge // print spaces in the interior for(int j = 1; j <=rows; j++) if (j ==1|| j==rows || len==rows || len == 1 ) // on edge System.out.print(character); else System.out.print(" ");


Download ppt "Java Programming: From the Ground Up"

Similar presentations


Ads by Google