COP 3003 Object-Oriented Programming - Polymorphism Dr. Janusz Zalewski, Fall 2013 Prepared by Dr Dahai Guo Outline • Introduction to Polymorphism • Superclass Reference and Subclass Object • Abstract Classes and Methods • instanceof operator • Creating and Using Interfaces Introduction to Polymorphism (1/7) • Based on and enabled by inheritance. • Enables us to “program in the general” rather than “program in the specific”. • Makes systems easily extensible. – New classes can be added with little or no modification to the general portions of the program. Introduction to Polymorphism (2/7) class Animal public void move() class Fish public void move() class Mammal public void move() class Cat public void move() class Tortoise public void move() class Dog public void move() Introduction to Polymorphism (3/7) • Problem: – In classes Animal and Mammal, the move( ) method is hard to define, because it is too general (or abstract). – Keep this in mind. Introduction to Polymorphism (4/7) • What can polymorphism do for us? – Example: you want to write a simulation program where 100 animals are created randomly and are moving. • Without polymorphism – Generate four random numbers – Create four arrays (cats, dogs, fish, tortoises) using the random numbers as the sizes • What if we want to be random when creating each object? In other words, the program runs the random number generation method 100 times, instead of only four. Introduction to Polymorphism (5/7) • What can polymorphism do for us? – Animal animals[ ]=new Animal[100]; animal[0] animal[1] . . . animal[99] An Animal reference can refer to any class’s object as long as this class directly or indirectly inherits class Animal. Introduction to Polymorphism (6/7) • What can polymorphism do for us? – Animal animals[ ]=new Animal[100]; 1. /* creating 100 Animal-derived objects */ 2. … 3. for(int i=0; i<100;i++){ 4. // we do not know which actual object 5. // animals[i] references to, 6. // but polymorphism can decide the sub7. // class and invoke correct method 8. 9. } animals[i].move(); Question: Do we still need to implement the move method for class Animal? Introduction to Polymorphism (7/7) • The two most important points of polymorphism: – A superclass reference refers to a subclass object. (Note the opposite is a syntax error.) – Which subclass’s method to invoke is decided at the execution time. In detail, it depends on the data type of the object. Superclass Reference and Subclass Object (1/8) • A program can create an array of superclass references that refer to objects of many subclass types. • This is allowed because each subclass object is-a object of its superclass. This is referred to as dynamic binding. Superclass Reference and Subclass Object (2/8) • Anything wrong? – class Test1 { –} – class Test2 { –} – …… – Test1 test = new Test2(); – …… Superclass Reference and Subclass Object (3/8) • Note in the “reference object” relationship, the reference’s class must be the superclass of the object’s class or exactly the object’s class. Superclass Reference and Subclass Object (4/8) 1. 2. 3. 4. 5. class CommissionEmployee { } class BasePlusCommissionEmployee extends CommissionEmployee { } Superclass Reference and Subclass Object (5/8) 1. 2. CommissionEmployee employee = new BasePlusCommissionEmployee(…); 3. 4. 5. employee.toString(); // which method will be invoked? employee.earnings(); // which method will bei nvoked employee.getBaseSalary(); // which method will be invoked? Illegal Statement! Superclass Reference and Subclass Object (6/8) • Important: when invoking a subclass’s method through a superclass’s reference, this method must be declared in the super class. • If the method is subclass-specific, the program must first cast the superclass reference to the subclass reference a technique known as downcasting. Superclass Reference and Subclass Object (7/8) 1. 2. employee.getBaseSalary(); // illegal statement ((BasePlusCommissionEmployee)employee).getBaseSalary(); Superclass Reference and Subclass Object (8/8) • Benefit of polymorphism. – Animal animals[ ] = new Animal[100]; 1. /* creating 100 Animal-derived objects */ 2. … 3. for(int i=0; i<100;i++){ 4. animals[i].move(); 5. } Question: If another Animal-based class is created, do we need to change anything to the for loop? Abstract Classes and Methods (1/7) class Fish public void move() class Animal public void move() Difficult to define, because only “animal” is too abstract. class Mammal public void move() class Tortoise public void move() class Cat public void move() class Dog public void move() Abstract Classes and Methods (2/7) • Why do not we leave out the move method in class Animal? And what we actually want is to force the subclasses to implement this function. • This can be achieved by abstract classes. Abstract Classes and Methods (3/7) abstract class Animal public abstract void move(); class Fish public void move() class Mammal public void move() class Cat public void move() class Tortoise public void move() class Dog public void move() Now, all the classes, except Animal, must implement method move to be instantiated. Abstract Classes and Methods (4/7) • Rules: – An abstract method is declared using keyword abstract. – Once a class has at least one abstract method, it must be declared as abstract class. – Important: abstract classes cannot be used to instantiate objects, because they are incomplete. Abstract Classes and Methods (5/7) • Rules: (cont) – If a superclass is an abstract class, its subclasses must implement all the abstract methods in order to be instantiated objects; otherwise they are also abstract. – The previous statement implies that both the superclass and subclass can be abstract. Abstract Classes and Methods (6/7) abstract class Animal public abstract void move(); class Fish public void move() abstract class Mammal Does not implement move() class Cat public void move() class Tortoise public void move() class Cat public void move() •Class Mammal inherits abstract method move from class Animal and does not implement it. So method move remains abstract. Therefore, class Mammal is also abstract. •Now both Animal and Mammal are abstract. Abstract Classes and Methods (7/7) • Rules: (cont) – Classes that can be used to instantiate objects are called concrete classes. – The subclass of an abstract superclass can be abstract or concrete, depending on whether it implements all the abstract method(s) in the superclass. How Can We Find the Type of the Object? (1/7) • • • • • • • SuperClass superRef; superRef=new SubClass1(); …… superRef=new SubClass2(); …… superRef=new SubClass3(); …… superRef can be used to point to different subclass objects. How Can We Find the Type of the Object? (2/7) • Sometimes, we want to figure out what type of object is referenced in order to call subclass-specific methods. – …… – // are you sure a SubClass1 object is referenced? – ((SubClass1)superRef).method1(); – // are you sure a SubClass2 object is referenced? – ((SubClass2)superRef).method2(); – // are you sure a SubClass3 object is referenced? – ((SubClass3)superRef).method3(); How Can We Find the Type of the Object? (3/7) • instanceof operator – Can help figure out what type of object is referenced 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. if (superRef instanceof SubClass1) { // downcasting ((SubClass1)superRef).method1(); } if (superRef instanceof SubClass2) { // downcasting ((SubClass2)superRef).method2(); } if (superRef instanceof SubClass3) { // downcasting ((SubClass3)superRef).method3(); } How Can We Find the Type of the Object? (4/7) • Requirements of the operands of instanceof – The data type of the reference and the right operand must have inheritance relationship, directly or indirectly. How Can We Find the Type of the Object? (5/7) Employee HourlyEmployee CommissionEmployee SalariedEmployee BasePlusCommissionEmployee How Can We Find the Type of the Object? (6/7) • instanceof operator – 1. 2. 3. 4. 5. 6. Anything wrong? HourlyEmployee employee= new HourlyEmployee(); if(employee instanceof BasePlusCommissionEmployee) { System.out.println(“BasePlusCommissionEmployee”); } HourlyEmployee and BasePlusCommissionEmployee has neither direct nor indirect inheritance relationship. How Can We Find the Type of the Object? (7/7) • Downcasting 1. Employee employee = 2. new BasePlusCommissionEmployee(); 3. …… 4. if(employee instanceof 5. BasePlusCommissionEmployee) { 6. employee.setLastName(“Johnson”); 7. ((BasePlusCommissionEmployee)employee). 8. 9. } setBaseSalary(1000); Creating and Using Interfaces (1/12) • Interfaces are abstract classes without non-abstract methods. • An interface declaration begins with the keyword interface and contains only constants and abstract methods. • All interface methods are implicitly public and abstract. • All interface instance variables are implicitly public, static, and final. Creating and Using Interfaces (2/12) • Anything wrong? 1. interface MyInterface { 2. int i; 3. } i is final, so it must be initialized at the declaration. Creating and Using Interfaces (3/12) • Anything wrong? 1. interface MyInterface { 2. protected int test(); 3. } Any interface methods must be public and abstract. Creating and Using Interfaces (4/12) • To use an interface, a concrete class must specify that it implements the interface and must declare each method in the interface with the signature specified in the interface declaration. • An interface reference can point to the objects of classes that implement it and their subclasses. Creating and Using Interfaces (5/12) • Anything wrong? 1.interface MyInterface { 2. int test(); 3.} 4.class MyClass implements MyInterface { 5. protected int test(); 6.} One cannot change the access control of the interface method. Creating and Using Interfaces (6/12) Payable Invoice Employee HourlyEmployee CommissionEmployee SalariedEmployee BasePlusCommissionEmployee Creating and Using Interfaces (7/12) 1. interface Payable { 2. double getPaymentAmount(); 3. } 4. class Invoice implements Payable { 5. public double getPaymentAmount() { 6. … 7. } 8. … 9. } 10. abstract class Employee implements Payable { 11. // getPaymentAmount() not implemented 12. } Creating and Using Interfaces (8/12) • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Equivalent? abstract class Payable { public abstract double getPaymentAmount(); } class Invoice extends Payable { public double getPaymentAmount() { … } … } abstract class Employee extends Payable { getPaymentAmount not implemented } Creating and Using Interfaces (9/12) • Discussion: – One can often see, esp. in GUI programs, that classes are defined like • class MyClass extends ExistingClass • implements Interface1, Interface2, …Interfacex { • // a class can implement multiple interfaces • •} // implementations of interface methods Creating and Using Interfaces (10/12) • Discussion (cont): – One often faces the following situation: • There is some existing code. • But the existing code cannot exactly solve a new problem. • We want to take advantage of already-developed programs in solving the new problem. Creating and Using Interfaces (11/12) • Discussion (cont): Existing Program extends New Program implements New Problem Creating and Using Interfaces (12/12) • Discussion (cont): Existing Super-Class Program extends New Sub-Class Program implements New Interface Problem