Download presentation
Presentation is loading. Please wait.
Published byValentine Rice Modified over 9 years ago
1
Chapter 9 Polymorphism
2
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-2 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
3
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-3 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces To understand polymorphism, one must understand the term, ‘binding.’
4
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-4 Binding – Very Important!! Consider the following method invocation: obj.doIt(); At some point, this object invocation (reference) 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 in object, obj, 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 Discussion ahead…
5
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-5 Polymorphism The term polymorphism literally means "having many forms" A polymorphic reference is a reference that can refer to different types of objects (that is, objects of different classes) at different points in time – despite what the source code looks like! A method invoked via a polymorphic reference can change from one invocation to the next, that is the reference can invoke a ‘ different’ object’s method (with same name) at different points in time! Restated: Consider 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 change during the execution of the program.) All object references in Java are potentially polymorphic due to late binding (dynamic binding)
6
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-6 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 is new! So the reference can refer to the job object or any objects inheriting from Occupation. This “compatibility” can be established using inheritance or using interfaces Careful use of polymorphic references can lead to elegant, robust software designs
7
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-7 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces
8
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-8 References and Inheritance As stated, 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 (that is, Christmas is derived from Holiday), then a Holiday reference (‘day’, in this case) could be used to point to a Christmas object. This means that day could point to an object of type Holiday or an object of any derived type! 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, a derived class of Holiday. day is a reference to the base class, but it points to Christmas here. Holiday Christmas
9
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-9 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 (reference) 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
10
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-10 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! Object being referenced was of type Christmas; Recall: day = new Christmas; Reference type was of type Holiday. It is very common to have a pointer to a base class (Holiday here) pointing to a derived object (day, of type Christmas here).
11
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-11 So, we could have the Holiday day; … Says, day is a reference to objects of type Holiday And later in code, day = new Christmas; day = new Easter; day = new Thanksgiving; These can appear at various places in the code…. And then, these references are each bound during run time depending on the program logic; that is, depending on what path in the program is taken binding will take place at the time the new object is referenced. Further, all three references can be used at various places in the code and – at that time – will point to the correct object.
12
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-12 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 The program logic will determine this during the execution of the program.
13
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-13 Let’s consider a practical example from your book. Be sure to go through this to understand it. We will go slowly…
14
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-14 Polymorphism via Inheritance Consider the following class hierarchy: (Discuss) StaffMember ExecutiveHourly VolunteerEmployee
15
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-15 /******************************************************************** // 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 personnel of type Staff. personnel.payday(); // This appears to invoke the payday method found in personnel. } }// end main() Let’s look at personnel…
16
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-16 // Staff.java Author: Lewis/Loftus Represents the personnel staff of a particular business. public class Staff { private StaffMember[] staffList; 1 of 2 // we are creating a reference to array of StaffMember references. // This is merely a nulll pointer at this time. Array of null pointers has not yet been allocated. public Staff () // Constructor: Sets up the list of staff members when ‘personnel’ was declared: { staffList = new StaffMember[6]; //Creates array of six null pointers. Code below initializes objects. 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. // (seven 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); // invokes Employee Constructor (six slides down) 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 many different StaffMember objs. ((Executive)staffList[0]).awardBonus (500.00); // narrowing…via cast operator ((Hourly)staffList[3]).addHours (40); } // end staff method.. We have just created an object of type Staff called ‘personnel’ on previous slide…
17
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-17 So, what did we do? We created six pointers to objects of the base class but declared six objects of derived classes. So, we have pointers to the base class (remember Holiday day ) with objects of the derived classes (remember day = new Christmas) So staffList[i] are pointers to the base class but can / will point to derived objects…
18
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-18 // Staff.java Author: Lewis/Loftus Represents the personnel staff of a particular business. public class Staff CLASS DEFINITION: CONTINUING FROM PREVIOUS SLIDE…. { private StaffMember[] staffList; 2 of 2 // we are creating a reference to array of StaffMember references. // This is merely a nulll pointer at this time. Array of null pointers has not yet been allocated. ….. 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 pay() in the object to which staffList[count] points to…. if (amount == 0.0) // Notice that each class object has its own pay() method!!! // Reference will invoke proper method! System.out.println ("Thanks!"); else System.out.println ("Paid: " + amount); System.out.println ("-----------------------------------"); } // endfor } // end payday() }// end Staff class
19
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-19 // 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 >, 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; }// end toString() // Derived classes must define the pay method for each type of employee. public abstract double pay(); // NO PARAMS; RETURNS DOUBLE. BY DEFINING pay() ABSTRACTLY HERE IN STAFFMEMBER, THE payday METHOD OF STAFF must be implemented in the derived classes. WE will POLYMORPHICALLY PAY EACH EMPLOYEE.}
20
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-20 The StaffMember class (previous slide) is abstract because it is not intended to be instantiated. It serves as a placeholder in the inheritance hierarchy to help organize and manage objects polymorphically. Notice it also contains both concrete and abstract members!! But notice in the previous slide: public class Staff { private StaffMember[] staffList; // At this point we are creating a single null reference, staffList, which appears as if it will point to an array of StaffMembers objects. But StaffMember is an abstract class, so it cannot be instantiated. But we can create both abstract and concrete methods and an array of references which can be inherited by all of its derived classes/objects. But note when we create the objects the references point to, they cannot be StaffMember objects because we cannot have objects of an abstract class. And, indeed (below), the objects are not StaffMember objects; they are Executive objects, Volunteer objects, etc. public Staff () // Constructor: { staffList = new StaffMember[6]; // actually creates an array of six null pointers. staffList[0] = new Executive ("Sam", "123 Main Line", "555-0469", "123-45-6789", 2423.07); // sets pointer to point to an Executive object, etc. More on Polymorphism and Abstract Classes
21
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-21 The pay method has no meaning at the StaffMember level, so it is declared to be abstract. But by declaring it there, we guarantee that every object of its children will have a pay method! (All derived classes must ‘implement’ the pay method for their respective objects. This allows us to create an array of StaffMember objects, which is actually filled with various types of staff members, and pay each one. The details of being paid are determined by each class as appropriate. More on Polymorphism and Abstract Classes - 2
22
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-22 //******************************************************************** // 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 }// end Constructor // OBJECT ATTRIBUTES. //----------------------------------------------------------------- // Returns a zero pay value for this volunteer. //----------------------------------------------------------------- public double pay() { return 0.0; }// end double pay() } // end Volunteer class
23
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-23 //******************************************************************** // 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; } } // end Employee class
24
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-24 // 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, String socSecNumber, double rate) { super (eName, eAddress, ePhone, socSecNumber, rate); //REFERENCES EMPLOYEE CONSTRUCTOR bonus = 0; // bonus has yet to be awarded // AND SETS instance variable ‘BONUS’ = 0 }// end Constructor // Awards the specified bonus to this executive. public void awardBonus (double execBonus) // INVOKED BY THE payday METHOD IN ‘STAFF’. { bonus = execBonus; }// end awardBonus //----------------------------------------------------------------- // 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; }// end double pay() }// end class
25
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-25 // 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; }// end Constructor // Adds the specified number of hours to this employee's accumulated hours. public void addHours (int moreHours) { hoursWorked += moreHours; }.// end addHours() public double pay() // Computes and returns the pay for this hourly employee { double payment = payRate * hoursWorked; hoursWorked = 0; return payment; }// end double pay() public String toString() { String result = super.toString(); result += "\nCurrent hours: " + hoursWorked; return result; }// end toString() } // end Hourly class
26
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-26 Outline Polymorphic References Polymorphism via Inheritance Polymorphism via Interfaces
27
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-27 Polymorphism via Interfaces An interface name can be used as the type of an object reference variable Assume we have: public interface Speaker()… and the reference: Speaker current; The current reference can be used to point to any object of any class that implements the Speaker interface (Recall, there can be no objects of the interface itself) Then, given: current.speak(); The version of speak that the following line invokes depends on the object that current is referencing. Recognizing that a number of classes can implement an interface, this binding is done during run time.
28
© 2004 Pearson Addison-Wesley. All rights reserved 27 9-28 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();
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.