220 likes | 282 Views
Polymorphism. Polymorphism enables you to write programs that process objects that share the same base class (either directly or indirectly) as if they are all objects of the base class. This can simplify programming.
E N D
Polymorphism • Polymorphism enables you to write programs that process objects that share the same base class (either directly or indirectly) as if they are all objects of the base class. • This can simplify programming. • From a practical programming viewpoint, polymorphism (runtime) manifests itself in two forms in Java: method overriding through inheritance hierarchy and method overriding through the Java interface. tMyn
With runtime polymorphism based on method overriding, the decision as to which version of a method will be executed is based on the actual type of object whose reference is stored in the reference variable, and not on the type of the reference variable on which the method is invoked. • The decision as to which version of the method to invoke cannot be made at compilation time. • That decision must be deferred and made at runtime. • This is sometimes referred to as late binding or dynamic binding. tMyn
The first example deals with the method overriding through inheritance: tMyn
package TimoSoft; public class Employee { protected String name; protected String address; public Employee(String naVal, String adVal) { System.out.println("Employee constructor."); setName(naVal); setAddress(adVal); } public void setName(String naValue) { name=naValue; } tMyn
public void setAddress(String adValue) { address=adValue; } public void mailCheck() { System.out.println("Mailing a check to "+this.name+ " "+this.address+"."); } } tMyn
package TimoSoft; public class Salary extends Employee { protected double salary; public Salary(String newNam, String newAdd, double newSal) { super(newNam, newAdd); System.out.println("Salary constructor."); setSalary(newSal); } public void setSalary(double salVal) { salary=salVal; } public void mailCheck() { System.out.println("Mailing a check to "+this.name+ " "+this.address+" with salary "+this.salary+"."); } } tMyn
package TimoSoft; public class Test { public static void main(String[] args) { Employee reference=null; Employee first=new Employee("Heikki Malinen", "Patteristonkatu 3"); first.mailCheck(); Employee second=new Salary("Erkki Karppanen", "Patteristonkatu 7", 3035.85); second.mailCheck(); Salary third=new Salary("Kirsi Taivalantti", "Patteristonkatu 9", 4076.25); third.mailCheck(); reference=first; reference.mailCheck(); reference=second; reference.mailCheck(); reference=third; reference.mailCheck(); } } tMyn
Employee constructor. Mailing a check to Heikki Malinen Patteristonkatu 3. Employee constructor. Salary constructor. Mailing a check to Erkki Karppanen Patteristonkatu 7 with salary 3035.85. Employee constructor. Salary constructor. Mailing a check to Kirsi Taivalantti Patteristonkatu 9 with salary 4076.25. Mailing a check to Heikki Malinen Patteristonkatu 3. Mailing a check to Erkki Karppanen Patteristonkatu 7 with salary 3035.85. Mailing a check to Kirsi Taivalantti Patteristonkatu 9 with salary 4076.25. BUILD SUCCESSFUL (total time: 1 second) tMyn
From the preceding example: • First of all, polymorphism works with derived class objects. • A reference to a derived class object must be stored in a variable (the name of the variable was reference in the previous example!) of a direct or indirect base class type for polymorphism to work. • The method called must be defined in the derived class. • The method called must also be declared as a member of the base class. • The method signatures for the method in the base and derived classes must be the same. tMyn
Either the method return type must be the same in the base and derived classes or the method return type in the derived class must be covariant (a subclass of the base class type). • The method access specifier must be no more restrictive in the derived class than in the base. tMyn
When you call a method using a variable of a base class type, polymorphism results in the method that is called being selected based on the type of the object stored, not the type of the variable. • Because a variable of a base type can store (is able to store) a reference to an object of any derived type, the kind of object stored will not be known until the program executes. • This behavior is referred to as virtual method invocation. tMyn
Thus the choice of which method to execute has to be made dynamically when the program is running – it cannot be determined when the program is compiled. • Consider from the previous example: When the compiler sees the line reference.mailCheck();, the compiler sees the mailCheck() method in the Employee class. So we can say that in compilation time, the compiler used mailCheck() in Employee class to validate the statement. At run time, however, the JVM invokes mailCheck() in the Salary class in those situations where the type of the object stored is Salary, so the type of the variable reference does not determine it. tMyn
The second example covers method overriding through the Java interface, so using interface as a type. • As stated earlier, you can’t create objects of an interface type, but you can create a variable of an interface type. • That variable can be used to store a reference to an object of any class type that implements that interface. • This means that you can use this variable to call the methods declared in the interface polymorphically. tMyn
package TimoSoft; public interface RemoteControl { void powerOnOff(); int volumeUp(int increment); int volumeDown(int decrement); } tMyn
package TimoSoft; public class TV implements RemoteControl { protected static int MIN_VOLUME=0; protected static int MAX_VOLUME=100; protected static boolean power=false; protected int volume; public TV(int volVal) { System.out.println("TV constructor."); setPower(); setVolume(volVal); } public void setVolume(int volValue) { volume=volValue; } tMyn
public void setPower() { power=true; System.out.println("TV is now on."); } public void powerOnOff() { power=!power; if(power) System.out.println("TV is now on"); else System.out.println("TV is now off"); } tMyn
public int volumeUp(int increment) { if(!power) return 0; volume=volume+increment; volume=Math.min(volume, MAX_VOLUME); System.out.println("TV is on, volume is "+volume+"."); return volume; } public int volumeDown(int decrement) { if(!power) return 0; volume=volume-decrement; volume=Math.max(volume, MIN_VOLUME); System.out.println("TV is on, volume is "+volume+"."); return volume; } } tMyn
package TimoSoft; public class DVD implements RemoteControl { protected static int MIN_VOLUME=0; protected static int MAX_VOLUME=100; protected static boolean power=false; protected int volume; public DVD(int volVal) { System.out.println("DVD constructor."); setPower(); setVolume(volVal); } public void setVolume(int volValue) { volume=volValue; } tMyn
public void setPower() { power=true; System.out.println("DVD is now on."); } public void powerOnOff() { power=!power; if(power) System.out.println("DVD is now on"); else System.out.println("DVD is now off"); } tMyn
public int volumeUp(int increment) { if(!power) return 0; volume=volume+increment; volume=Math.min(volume, MAX_VOLUME); System.out.println("DVD is on, volume is "+volume+"."); return volume; } public int volumeDown(int decrement) { if(!power) return 0; volume=volume-decrement; volume=Math.max(volume, MIN_VOLUME); System.out.println("DVD is on, volume is "+volume+"."); return volume; } } tMyn
package TimoSoft; public class Test { public static void main(String[] args) { RemoteControl remote=null; TV first=new TV(10); first.volumeUp(10); first.powerOnOff(); DVD second=new DVD(40); second.volumeDown(15); second.powerOnOff(); remote=first; remote.powerOnOff(); remote.volumeDown(5); remote=second; remote.powerOnOff(); remote.volumeUp(25); } } tMyn
run: TV constructor. TV is now on. TV is on, volume is 20. TV is now off DVD constructor. DVD is now on. DVD is on, volume is 25. DVD is now off TV is now on TV is on, volume is 15. DVD is now on DVD is on, volume is 50. BUILD SUCCESSFUL (total time: 2 seconds) tMyn