SE 360 Advances in Software Development Object Oriented Development in Java Polymorphism Dr. Senem Kumova Metin Modified lecture notes of Dr. Hüseyin Akcan
Inheritance Object oriented programming languages allow classes to inherit commonly used state and behavior from other classes CODE REUSE How to factor out the commonalities of various classes?? Find out IS-A RELATIONSHIPS A mammal is a vertebrate A dog is a mammal Superclass (parent) contains all the attributes and behaviors that are common to classes that inherit from it (subclasses)
Inheritance : Classification of Vertebrates Arrows represent is-a relationship
Inheritance: A Simple Example
Abstract Classes
Polymorphism Dictionary Definition of Polymorphism: The quality of being able to assume different forms In the context of programming: A program part is polymorphic if it can be used for objects of several types
Polymorphism Polymorphism is tightly coupled to inheritance In inheritance hierarchy, all subclasses inherit the interfaces from their superclass. However each subclass is a separate entitiy, each might require a different response to same message!! Polymorphism supports different responses
Polymorphism : Example public abstract class Shape{ protected double area; public abstract double getarea();} public class Circle extends Shape{ double radius; public Circle(double r) { radius=r;} public double getarea() { area=3.14*radius*radius; return (area) ;} }
Example Paint program Assume you have to write a print program to display the following: circle, rectangle, square You create a class for each of them, and implement a print() method Also you want to keep the runtime objects in a single array, and whenever a refresh is needed, call the print() method of each object in this array How would you do it?
class Shape { Example 1. public void print() { System.out.println("Shape::print"); } } class Triangle extends Shape { public void print(){system.out.println("triangle::print"); } } class Circle extends Shape { public void print(){system.out.println("circle::print"); } } public class Example1 { public static void show(shape s){ s.print(); } public static void main(string[] args) { Triangle t=new Triangle(); Circle c=new Circle(); show(t); show(c); ; } }
Example 1. What happens if print() in class Shape is removed? class Shape {} class Triangle extends Shape { public void print(){system.out.println("triangle::print"); } } class Circle extends Shape { public void print(){system.out.println("circle::print"); } } public class Example1 { public static void show(shape s){ s.print(); } public static void main(string[] args) { Triangle t=new Triangle(); Circle c=new Circle(); show(t); show(c); ; } }
Example 1. What happens if Shape class is an abstract class? abstract class Shape { public abstract void print();} class Triangle extends Shape { public void print(){ System.out.println("Triangle::print"); } } class Circle extends Shape { public void print(){ System.out.println("Circle::print"); } } public class Example1 { } public static void show(shape s){ s.print(); } public static void main(string[] args) { Triangle t=new Triangle(); Circle c=new Circle(); show(t); show(c); }
class Shape { Example 2. public void print() { System.out.println("Shape::print"); } } class Triangle extends Shape { public void print(){system.out.println("triangle::print"); } } class Circle extends Shape { public void print(){system.out.println("circle::print"); } } public class Example2 { public static void show(shape s){ s.print(); } public static void main(string[] args) { } Shape s; s= new Shape(); System.out.println("I am a " +s); show(s); s= new Triangle(); System.out.println("I am a " +s); show(s); s= new Circle(); System.out.println("I am a " +s); show(s); }
Example 3. class Shape { public void print() { System.out.println("Shape::print"); } } class Triangle extends Shape { public void print(){ System.out.println("Triangle::print"); } } class Circle extends Shape { public void print(){ System.out.println("Circle::print"); } } public class Example3 { public static void show(shape[] s){ for (int i=0; i<s.length; i++) { System.out.println("I am a" +s); s[i].print(); } } public static void main(string[] args) { Shape [] sarray= new Shape[2]; sarray[0]= new Triangle(); sarray[1]= new Circle(); show(sarray); }
Method binding Method binding means connecting a method call to the method body Static binding C/C++ Dynamic binding C++/Java/Python Also called polymorphism, late-binding, runtime binding
Method binding (2) Java uses dynamic binding for all method calls Except final (private) and static methods Has a slight performance penalty compared to static binding
Stages of Binding in Java 1. Compiler looks at the declared type of the object and the method name 2. Compiler uses overload resolution policy to determine candidates 3. If the method is private, final or a constructor then static binding is used. 4. When program uses dynamic binding to call a method, then the virtual machine must call the version of the method that is appropriate for the actual type of the object
Dynamic Binding in Java 1. Virtual machine fetches the method table for the actual type of the object 2. Virtual machine looks up the defining class for the method signature 3. Virtual machine calls the method
Advantages Lets you express your design by using the base class and its methods Later you can extend the design as much as you like, add new objects etc. As long as they use the base class methods, they work with methods that accept base class type You can extend your programs without modifying existing code. Assume you add an Executive class later The existing e.getdescription() calls Executive.getDescription method automatically without needing to recompile the existing code
Advantages(2)
Design decisions In order to use the advantages of polymorphism write methods that communicate with the base class directly Lets you extend the design without changing the interface of the base class, or the methods Extend your design by inheriting new types from the base class The base class methods, and methods that communicate with the base class do not change
Base class methods In polymorphism, base class methods are for expressing design They should not be called in a proper design They should redirect the call to the appropriate derived class You can also define base class as abstract class!
Downcasting Converting the base class type to the original type Upcasting is always safe A triangle is a shape How about downcasting?
Downcasting(2) In C++ you use RTTI to find the original type dynamic_cast<...> In Java each cast is safe, so downcasting is also safe Otherwise you get ClassCastException
Example. Downcasting Try to call a subclass method which is not a inherited by a superclass type reference to an object of subclass!! class Shape1 { public void A() { System.out.println("Shape1::A()"); } } class Triangle1 extends Shape1 { public void A() { System.out.println("Triangle1::A()"); } public void B() { System.out.println("Triangle1::B()"); } } public class Downcast { public static void main(string[] args) { Shape1[] sarray= new Shape1[2]; sarray[0]= new Triangle1(); sarray[1]= new Shape1(); sarray[0].a(); //sarray[0].b(); // NOT VALID Every shape is not a triangle ((Triangle1)sArray[0]).B(); } }