Presentation is loading. Please wait.

Presentation is loading. Please wait.

Polymorphism What is Polymorphism? Taking Advantage of Polymorphism

Similar presentations


Presentation on theme: "Polymorphism What is Polymorphism? Taking Advantage of Polymorphism"— Presentation transcript:

1 Polymorphism What is Polymorphism? Taking Advantage of Polymorphism
Down-Casting Advantages of Polymorphism Unit 04

2 What is Polymorphism? Polymorphism means many forms (it derives from the Greek words Poly, meaning many, and Morphos, meaning form). In Java, the term is used in a number of ways. For example, we recall that a reference of type superclass can be assigned an object of any of its subclasses. Similarly, a reference of type a given interface can be assigned an object of any class that implements the interface. These types of references are therefore called polymorphic references - since they can take different forms. Unit 04

3 What is Polymorphism? -Cont’d
However, the polymorphism which we consider is this lecture, is that which involves binding of method calls to particular methods. We explain this using an example. Recall our Shapes example discussed in the Abstract classes lecture. Unit 04

4 What is Polymorphism? -Cont’d
With these classes in mind, consider the following application and its output. public class TestShapes{ public static void main(String[] args){ Shape[] shape = new Shape[3]; shape[0] = new Rectangle(5, 10); shape[1] = new Square(10); shape[2] = new Circle(15); for(int i = 0; i<shape.length; i++){ System.out.println("\n"+shape[i].name()); System.out.println("Perimeter: "+shape[i].perimeter()); System.out.println("Area: "+shape[i].area()); } The application creates each type of shape and prints its properties. Unit 04

5 What is Polymorphism? -Cont’d
First, we note that because the references (of type Shape) in the array, shape, are polymorphic, we are able to store all the three types of shapes in one array. Second, and the most important point, the same set of statements produced three different outputs. for(int i = 0; i<shape.length; i++){ System.out.println("\n"+shape[i].name()); System.out.println("Perimeter: "+shape[i].perimeter()); System.out.println("Area: "+shape[i].area()); } Unit 04

6 What is Polymorphism? -Cont’d
How does the system know which area method to call from the statement, shape[i].area(), given that the reference type is Shape? The answer, as far as Java Compiler is concerned is “I don’t know”. That is this question cannot be answered at compilation time. It is only possible to answer this question after knowing the actual type of object being referenced by the reference variable shape[i]. The association of a method call to a particular method is called binding, and Java exhibits what is called run-time binding, also called dynamic binding or late-binding. Unit 04

7 What is Polymorphism? -Cont’d
Java uses late-binding for all methods except those that are declared as final. In other languages such as Pascal, binding is determined by the compiler. Such languages are said to exhibit early or static binding. Since binding takes place at run-time in Java, it is possible to write code that executes differently depending on the actual object. This behavior, whereby the same code executes differently, depending on the object it acts on is what is called polymorphism. Unit 04

8 Taking Advantage of Polymorphism
Since binding takes place at run-time, it is possible to make a call to abstract methods, since by the time the code executes, the methods would have been implemented. For example, we can modify the Shape class as follows: public abstract class Shape{ public String name(){ return getClass().getName(); } public abstract double area(); public abstract double perimeter(); public String toSring(){ return name()+"\nPerimeter: "+perimeter()+"\nArea: "+area(); Note that the toString method is calling the area and perimeter methods even though they are declared abstract. Unit 04

9 Taking Advantage of Polymorphism – Cont‘d
With this modification, the application can now be simplified as follows and it produces the same output as before: public class TestShapes{ public static void main(String[] args){ Shape[] shape = new Shape[3]; shape[0] = new Rectangle(5, 10); shape[1] = new Square(10); shape[2] = new Circle(15); for(int i = 0; i<shape.length; i++) System.out.println(shape[i]); } The println calls the toString method of the object. Since the method is not overridden in the subclasses, that of the super class is used. Due to polymorphism, the call to perimeter and area methods in toString method will be bound to those of the actual object. Unit 04

10 Down-Casting We have seen that an object of a subclass can be assigned to a reference variable of type superclass –Up-casting A natural question to ask is, does Java allow the reverse? Assigning an object of a superclass to a reference of type subclass, called down-casting, can also be done, but it is considered to be a narrowing conversion and must be done with a cast. In fact down-casting is only advisable if the object being down-cast is actually of the subclass type, which was up-cast to the superclass and now being down-cast back to the subclass. Unit 04

11 Down-Casting –Cont’d A good question now is, why would it be necessary to go through this circle of up-casting and then down-casting? To answer this question, we take the following example: import java.util.*; public class TestShapes2{ public static void main(String[] args){ Vector shape = new Vector(3); shape.add(new Rectangle(5, 10)) shape.add(new Square(10)); shape.add(new Circle(15)); System.out.println("Shape\tArea"); System.out.println("***************************"); for(int i = 0; i<shape.size(); i++){ Shape nextShape = (Shape)shape.get(i); System.out.println(nextShape.name()+"\t"+nextShape.area()); } Unit 04

12 Down-Casting –Cont’d In our example, if the method we want to call is not in the superclass Shape, then we still need to down-cast further. For example, suppose that the Circle class has an additional method, public double getRadius(), and we wish to call this method. Then we must down-cast the object returned by the get method to Circle. But how do we know that the actual object is of type Circle. Fortunately, Java has an operator, instaceof, which we can use to check the actual type of an object. for(int i = 0; i<shape.size; i++){ Shape nextShape (Shape)shape.get(i); System.out.println(nextShape.name()+"\t"+nextShape.area()); if(nextShape instanceOf Circle){ Circle circle = (Circle)nextShape; System.out.println("Radius = "+circle.getRadius()); } Unit 04

13 Down-Casting –Cont’d Although the Compiler will allow down-casting even if the actual object is not of type the subclass being down-cast to, a run-time error will result if the resulting reference is used to call a method that does not exists. To avoid this, it is advisable to always use the instanceof operator to check the type of objected before down-casting it. Employee emp1 = new MonthlyEmployee("Sahalu Junaidu"); if(emp1 instanceof HourlyEmployee){ HourlyEmployee emp2 = (HourlyEmployee)emp1; emp2.addHours(60); } Unit 04

14 Advantages of Polymorphism
To conclude, we take a quick look at the advantages of polymorphism Generic Code: Polymorphism allows us to write code that can be applied to different types of objects and get different result based on the object. There is no need to write separate code for each type. Extensibility: It allows the functionality of a code to be extended. For example, if we define another subclass of Shape, Triangle, then the same code in our application can be used to process Triangle shapes as well. Unit 04

15 Advantages of Polymorphism – Cont’d
Readability: It is obviously more readable to have a statement like: Rather than: for(int i = 0; i<munShapes; i++){ switch(shapeType[i]){ 'c': System.out.println(circleArea()); break; 's': System.out.println(squareArea()); break; ... } In fact any time you find yourself doing the later, it is a pointer to re-think your code. It probably could be made more Polymorphic. Unit 04

16 Exercises 1(a). Write a class, Triangle, that extends Shape, and has three instance variable, side1, side2, side3. Implement the area and perimeter methods. Note: area = SQRT(s(s-side1)(s-side2)(s-side3)), where, s = perimeter/2. (b). Write a class, TestShapes, that creates an instance of each of our shape classes and prints it. 2(a). Write an interface, Zakatable, that has a method getZakat() and a constant, ZAKAT_RATE= 0.025 (b).Write a class, IslamicBankAccount, that implements Zakatable. It has methods: deposit, withdraw, getBalance, and addDivident, which is used to add profit or loss to the account. (c).Modify the Employee abstract class so that it implements Zakatable. (d).Write a test class, that has two methods: void PrintZakat(Zakatable o) that prints the zakat from any zakatable object, o; and a main method that creates instances of MonthlyEmployee and IslamicBankAccount and print their zakat. Unit 04


Download ppt "Polymorphism What is Polymorphism? Taking Advantage of Polymorphism"

Similar presentations


Ads by Google