Chapter 9 Polymorphism Polymorphism • Polymorphism is an object-oriented concept that allows us to create versatile software designs • Chapter 9 focuses on: defining polymorphism and its benefits using inheritance to create polymorphic references using interfaces to create polymorphic references using polymorphism to implement sorting and searching algorithms © 2004 Pearson Addison-Wesley. All rights reserved 24 9-2 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces Sorting Searching © 2004 Pearson Addison-Wesley. All rights reserved 24 9-3 Binding • Consider the following method invocation: obj.doIt(); • At some point, this invocation is bound to the definition of the method that it invokes • If this binding occurred at compile time (and this is what we are used to…), then that line of code would call the same method every time • However, Java defers method binding until run time -- this is called dynamic binding or late binding. This is an extremely important feature!!! • Late binding provides flexibility in program design © 2004 Pearson Addison-Wesley. All rights reserved 24 9-4 Polymorphism • The term polymorphism literally means "having many forms" • A polymorphic reference is a variable that can refer to different types of objects at different points in time • The method invoked through a polymorphic reference can change from one invocation to the next. • (e.g. Obj.doit; With dynamic binding, this may refer to different methods in different objects at different points during execution! All methods will have the name, doit, but the objects that they are in may vary!) • All object references in Java are potentially polymorphic due to late binding (dynamic binding) © 2004 Pearson Addison-Wesley. All rights reserved 24 9-5 Polymorphism • Suppose we create the following reference variable: Occupation job; • As written, this creates a ‘reference’ to an object (not yet created) of type Occupation. • Java allows this reference to point to an Occupation object (which we know), or to any object of any ‘compatible’ type (like derived types of Occupation!) • This “compatibility” can be established using inheritance or using interfaces • Careful use of polymorphic references can lead to elegant, robust software designs © 2004 Pearson Addison-Wesley. All rights reserved 24 9-6 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces Sorting Searching © 2004 Pearson Addison-Wesley. All rights reserved 24 9-7 References and Inheritance • An object reference can refer to an object of its class, or to an object of any class related to it by inheritance • For example, if the Holiday class is used to derive a class called Christmas, then a Holiday reference (‘day’, in this case) could be used to point to a Christmas object Holiday Christmas Holiday day; // day is a ref to Holiday object (Holiday object not yet created) day = new Christmas(); // Here, day is an object of type Christmas and hence points to Christmas. © 2004 Pearson Addison-Wesley. All rights reserved 24 9-8 References and Inheritance • Assigning a child object to a parent reference is considered to be a widening conversion, and can be performed by simple assignment this is exactly what we did in the last slide. (a pointer to the base class is actually pointing to an object of a derived type.) • The opposite: Assigning an parent object to a child reference can be done also, but it is considered a narrowing conversion and must be done with a cast • The widening conversion is the more useful © 2004 Pearson Addison-Wesley. All rights reserved 24 9-9 Polymorphism via Inheritance • In polymorphism: It is the type of the object being referenced, not the reference type, that determines which method is invoked. • In previous slides, day is pointing to an object of type Christmas! • It is very common to have a pointer to a base class pointing to a derived object. © 2004 Pearson Addison-Wesley. All rights reserved 24 9-10 More • Suppose the Holiday class has a method called celebrate, and the Christmas class overrides it; that is, Christmas also has a method called celebrate. • Now consider the following invocation: day.celebrate(); • If (during execution) day refers to (points to) a Holiday object, it invokes the Holiday version of celebrate; if it refers to a Christmas object, it invokes the Christmas version © 2004 Pearson Addison-Wesley. All rights reserved 24 9-11 • Let’s consider a practical example from your book. • Be sure to go through this to understand it. © 2004 Pearson Addison-Wesley. All rights reserved 24 9-12 Polymorphism via Inheritance • Consider the following class hierarchy: (Discuss) StaffMember Volunteer Employee Executive © 2004 Pearson Addison-Wesley. All rights reserved Hourly 24 9-13 /******************************************************************** // Firm.java Author: Lewis/Loftus // // Demonstrates polymorphism via inheritance. //******************************************************************** public class Firm //----------------------------------------------------------------// Creates a staff of employees for a firm and pays them. //----------------------------------------------------------------public static void main (String[] args) // Here is the driver!!! { Staff personnel = new Staff(); //creates an object (actually reference) to an object personnel of type Staff. personnel.payday(); // This appears to invoke the payday method found in personnel. } Let’s ©look at personnel… 2004 Pearson Addison-Wesley. All rights reserved 24 9-14 } // Staff.java Author: Lewis/Loftus Represents the personnel staff of a particular business. public class Staff We have just created an object of type { called ‘personnel’ on previous slide… private StaffMember[] staffList; // we are creating a reference to array called staffList of StaffMember objects (number of objects is unknown.). // This is merely a pointer to an array of references – that is ‘potential’ references to StaffMember objects. Staff public Staff () // Constructor: Sets up the list of staff members when ‘personnel’ was declared: Note: { staffList = new StaffMember[6]; // actually creates space for array of references (empty) to six objects. Below initializes each object. staffList[0] = new Executive ("Sam", "123 Main Line", "555-0469", "123-45-6789", 2423.07); // sets pointer to point to an Executive object and this object is initialized. staffList[0] points to this new object. Constructor of Executive is invoked. (four slides down) Note: an Executive object is_a StaffMember object too…. staffList[1] = new Employee ("Carla", "456 Off Line", "555-0101", "987-65-4321", 1246.15); // Employee Constructor staffList[2] = new Employee ("Woody", "789 Off Rocker", "555-0000", "010-20-3040", 1169.23); staffList[3] = new Hourly ("Diane", "678 Fifth Ave.", "555-0690", "958-47-3625", 10.55); staffList[4] = new Volunteer ("Norm", "987 Suds Blvd.", "555-8374"); // Uses Constructor of specified type. staffList[5] = new Volunteer ("Cliff", "321 Duds Lane", "555-7282"); // Array of references in Staff (personnel actually) points to a NUMBER of different StaffMember objects! ((Executive)staffList[0]).awardBonus (500.00); ((Hourly)staffList[3]).addHours (40); } public void payday () { double amount; for (int count=0; count < staffList.length; count++) { System.out.println (staffList[count]); amount = staffList[count].pay(); // polymorphic reference to object to which staffList[count] points to…. if (amount == 0.0) System.out.println ("Thanks!"); else System.out.println ("Paid: " + amount); System.out.println ("-----------------------------------"); © 2004 Pearson Addison-Wesley. All rights reserved 24 } // endfor } // end payday() 9-15 // StaffMember.java Author: Lewis/Loftus // Represents a generic staff member. //******************************************************************** abstract public class StaffMember // NOTE: ABSTRACT CLASS – NO OBJECTS! { // CAN HAVE REFERENCES, THOUGH! protected String name; // UNLIKE AN <<interface>>, can have attributes and // method bodies which may be overridden or used via inheritance protected String address; // CAN ALSO HAVE abstract METHODS, WHICH MUST BE // EXPANDED BY DERIVED CLASS, UNLESS IT IS ALSO ABSTRACT. protected String phone; //----------------------------------------------------------------// Sets up a staff member using the specified information. //----------------------------------------------------------------public StaffMember (String eName, String eAddress, String ePhone) // NOTICE: HAS CONSTRUCTOR { // BUT SINCE NO INSTANTIATION, WILL BE USED BY DERIVED CLASSES. name = eName; address = eAddress; phone = ePhone; } // Returns a string including the basic employee information. public String toString() // HAS toString ALSO – FOR USE BY INHERITANCE… { String result = "Name: " + name + "\n"; result += "Address: " + address + "\n"; result += "Phone: " + phone; return result; } // Derived classes must define the pay method for each type of employee. public abstract double pay(); // NO PARAMS; RETURNS DOUBLE. BY DEFINING pay() © 2004 Pearson Addison-Wesley. HERE All rights reserved 24 ABSTRACTLY IN STAFFMEMBER, THE payday METHOD OF STAFF CAN 9-16 POLYMORPHICALLY PAY EACH EMPLOYEE. //******************************************************************** // Volunteer.java Author: Lewis/Loftus // // Represents a staff member that works as a volunteer. //******************************************************************** public class Volunteer extends StaffMember INHERITANCE { // GETS NO COMPENSATION. //----------------------------------------------------------------// Sets up a volunteer using the specified information. //----------------------------------------------------------------public Volunteer (String eName, String eAddress, String ePhone) { super (eName, eAddress, ePhone); // USES SUPER TO INSTANTIATE } // OBJECT ATTRIBUTES. //----------------------------------------------------------------// Returns a zero pay value for this volunteer. //----------------------------------------------------------------public double pay() { return 0.0; } } // end Volunteer class © 2004 Pearson Addison-Wesley. All rights reserved 24 9-17 //******************************************************************** // Employee.java Author: Lewis/Loftus// // Represents a general paid employee. //******************************************************************** public class Employee extends StaffMember INHERITANCE AGAIN. { protected String socialSecurityNumber; NOTE: BASE CLASS ALSO! protected double payRate; // INFERRED FROM protected ATTRIBUTES. //----------------------------------------------------------------// Sets up an employee with the specified information. // CONSTRUCTOR public Employee (String eName, String eAddress, String ePhone, String socSecNumber, double rate) { super (eName, eAddress, ePhone); //USES ITS BASE CLASS VIA super REFERENCE. socialSecurityNumber = socSecNumber; // THEN TAKES CARE OF ITS OWN ATTRIBUTES. payRate = rate; //THESE WILL BE ACCESSIBLE TO ITS DERIVED CLASSES } //----------------------------------------------------------------// Returns information about an employee as a string. public String toString() { // OVERRIDES STAFFMEMBER’S toString… String result = super.toString(); //NOTE USES super FOR ‘SOME’ AND APPENDS THE REST result += "\nSocial Security Number: " + socialSecurityNumber; return result; } // Returns the pay rate for this employee. public double pay() // MERELY RETURNS ATTRIBUTE VALUE. { return payRate; } © 2004 Pearson Addison-Wesley. All rights reserved 24 } // end Employee class 9-18 // Executive.java Author: Lewis/Loftus // Represents an executive staff member, who can earn a bonus NB. //******************************************************************** public class Executive extends Employee INHERITANCE AGAIN. { private double bonus; // INHERITS FROM BOTH STAFFMEMBER AND EMPLOYEE public Executive (String eName, String eAddress, String ePhone, Note the Constructor! String socSecNumber, double rate) { super (eName, eAddress, ePhone, socSecNumber, rate); //REFERENCES EMPLOYEE CONSTRUCTOR bonus = 0; // bonus has yet to be awarded // AND SETS ‘BONUS’ TO ZERO. } // Awards the specified bonus to this executive. public void awardBonus (double execBonus) // INVOKED BY THE payday METHOD IN ‘STAFF’. { bonus = execBonus; } //----------------------------------------------------------------// Computes and returns the pay for an executive, which is the // regular employee payment plus a one-time bonus. //----------------------------------------------------------------public double pay() // OVERRIDES THE PAY METHOD OF EMPLOYEE TO ADD A BONUS, IF ANY. { double payment = super.pay() + bonus; bonus = 0; } } return payment; © 2004 Pearson Addison-Wesley. All rights reserved 24 9-19 // Hourly.java Author: Lewis/Loftus // Represents an employee that gets paid by the hour. //******************************************************************** public class Hourly extends Employee INHERITANCE… { private int hoursWorked; // Sets up this hourly employee using the specified information. public Hourly (String eName, String eAddress, String ePhone, // CONSTRUCTOR String socSecNumber, double rate) { super (eName, eAddress, ePhone, socSecNumber, rate); // USES EMPLOYEE REF. hoursWorked = 0; } // Adds the specified number of hours to this employee's accumulated hours. public void addHours (int moreHours) { hoursWorked += moreHours; }. public double pay() // Computes and returns the pay for this hourly employee { double payment = payRate * hoursWorked; hoursWorked = 0; return payment; } public String toString() { String result = super.toString(); result += "\nCurrent hours: " + hoursWorked; return result; © 2004 Pearson Addison-Wesley. All rights reserved 24 } } // end Hourly class 9-20 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces Sorting Searching © 2004 Pearson Addison-Wesley. All rights reserved 24 9-21 Polymorphism via Interfaces • An interface name can be used as the type of an object reference variable Speaker current; • The current reference can be used to point to any object class Speaker or any class that implements the Speaker interface • The version of speak that the following line invokes depends on the type of object that current is referencing current.speak(); © 2004 Pearson Addison-Wesley. All rights reserved 24 9-22 Polymorphism via Interfaces • Suppose two classes, Philosopher and Dog, both implement the Speaker interface, providing distinct versions of the speak method • In the following code, the first call to speak invokes one version and the second invokes another: Speaker guest = new Philospher(); guest.speak(); guest = new Dog(); guest.speak(); © 2004 Pearson Addison-Wesley. All rights reserved 24 9-23 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces Sorting Searching © 2004 Pearson Addison-Wesley. All rights reserved 24 9-24