Explore polymorphisms and their benefits in Java

Posted by David-fethiye on Mon, 16 Dec 2019 04:54:37 +0100

Polymorphism is one of the basic principles of object-oriented software.The term often refers to things that can take many forms.In an object-oriented approach, polymorphism makes it possible to write programs with late-bound references.Although it is easy to create polymorphic references in Java, the concepts behind them have a far-reaching impact on overall programming.In this paper, some complex details about polymorphisms and their impact on object-oriented programming are discussed in combination with the points of knowledge learned in the elite courses.

Polymorphic Reference: Overview

A polymorphic reference is a variable that can reference different types of objects at different points in time.It is usually compatible with the classes it references.For example, in the following cases:

Employee employee;

 

'employee'is a reference variable that can reference an instance of the Employee class.Reference variables restrict the reference object depending on its compatibility.This seems to be the only reliable condition, but it is not, especially when polymorphism is implemented.The rules are too strict, but by combining the idea of having multiple forms, polymorphism makes it more flexible.This means that polymorphic references guarantee that they can reference different types of objects at different points in time, rather than relying entirely on compatibility.Therefore, if you can invoke a method using a reference at a point in time, you can dynamically change it to point to another object and call another method the next time.This can take advantage of flexibility by providing another dimension to use reference variables.

When a reference variable is bound to an object that cannot be changed at run time, or in other words, when a method call and a method definition are bound at compile time, it is called a static binding.If a binding is changeable at run time, such as in the case of polymorphic references, the binding decision is made only during execution, it is called dynamic binding or late binding.Both are useful in object-oriented programming, and not both outperform the other.However, in the case of polymorphic references, the deferred binding promise offers flexibility over compile-time binding, but on the other hand, it reduces performance overhead.However, this is largely acceptable, and the overhead is often less attractive in terms of efficiency..

Create Polymorphism

In Java, polymorphic references can be created in two ways: using inheritance or using interfaces.

Inheritance Polymorphism

A reference variable references an instance of a class.For inheritance hierarchies, if the reference variable is declared as a parent type in the hierarchy tree, the reference object can point to an instance of any class in the hierarchy.This means that in Java, because Objectclass is the parent or superclass of all classes, or in other words, all classes in Java are actually subclasses of the Object class, implicitly or explicitly referencing variables to the object class.Object types can reference any class instance in Java.That's what we mean.

1 Employee employee;
2 Object object;
3 employee = new Employee();
4 object = employee;   // This is a valid assignment

 

If the opposite is true, the following is true:

1 Employee employee;
2 Object object = new Object();
3 employee = (Employee)object   // Valid, but needs explicit cast

 

Observe that it requires an explicit cast; only then can it become a valid declaration.You can see that this reverse allocation is not very useful for edges where problems occur in many cases.This is because the functionality of the Object instance has little to do with the expected functionality of the Employee reference variable.Relationship is-a can be derived from employee-is-an-object; in this case, the opposite relationship (for example, the object is an employee) is too far-fetched.

Inheritance polymorphism: an example

Let's try to understand it with examples.

 

Figure 1: Classes derived from driver classes, companies

A driver class called Companycreates a list of employees and calls the paySalary() method.The salary category maintains a list of different types of employees in the Company.Notice that the array is declared as an array of reference variables derived from the Employee class (parent or superclass of all employee subclasses).As a result, the array can be populated with object references created from any subclass of the Employee class (such as CommissionEmployee, HourlyEmployee, SalariedEmployee).In the paySalary() definition, the appropriate salary() method is called based on the object reference in the array.Therefore, calls to the salary() method are polymorphic, and it is clear that each class has its own version of the salary() method.

The employee array in the Payroll class does not represent a particular type of Employee.It serves as a handle that can point to any type of Employee subclass reference.Although inherited classes share some common data inherited as descendants, they have their own set of properties.

Implementing polymorphism through inheritance: a Java implementation

This is a quick implementation of the example in Java.

  1 package org.mano.example;
  2 public class Company
  3 {
  4    public static void main( String[] args )
  5    {
  6       Payroll payroll = new Payroll();
  7       payroll.paySalary();
  8    }
  9 }
 10 package org.mano.example;
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 public class Payroll {
 14    private List<Employee> employees =
 15       new ArrayList<>();
 16    public Payroll() {
 17       employees.add(new
 18             SalariedEmployee("Harry Potter",
 19          "123-234-345",7800));
 20       employees.add(new
 21             CommissionEmployee("Peter Parker",
 22          "234-345-456",2345.67,0.15));
 23       employees.add(new
 24             HourlyEmployee("Joker Poker",
 25          "456-567-678",562.36,239.88));
 26    }
 27    public void paySalary() {
 28       for (Employee e: employees) {
 29          System.out.println
 30             ("----------------------------------------------------");
 31          System.out.println(e.toString());
 32          System.out.printf
 33             ("Gross payment: $%,.2f\n",e.salary());
 34          System.out.println
 35             ("----------------------------------------------------");
 36       }
 37    }
 38 }
 39  
 40 package org.mano.example;
 41  
 42 public abstract class Employee {
 43    protected String name;
 44    protected String ssn;
 45    public Employee(String name, String ssn) {
 46       this.name = name;
 47       this.ssn = ssn;
 48    }
 49    public String getName() {
 50       return name;
 51    }
 52    public void setName(String name) {
 53       this.name = name;
 54    }
 55    public String getSsn() {
 56       return ssn;
 57    }
 58    public void setSsn(String ssn) {
 59       this.ssn = ssn;
 60    }
 61    @Override
 62    public String toString() {
 63       return String.format("%s\nSSN: %s",
 64          getName(),getSsn());
 65    }
 66    public abstract double salary();
 67 }
 68  
 69 package org.mano.example;
 70 public class SalariedEmployee extends Employee {
 71    protected double basicSalary;
 72    public SalariedEmployee(String name, String ssn,
 73          double basicSalary) {
 74       super(name, ssn);
 75       setBasicSalary(basicSalary);
 76    }
 77    public double getBasicSalary() {
 78       return basicSalary;
 79    }
 80    public void setBasicSalary(double basicSalary) {
 81       if(basicSalary>= 0.0)
 82          this.basicSalary = basicSalary;
 83       else
 84          throw new IllegalArgumentException("basic " +
 85             "salary must be greater than 0.0");
 86    }
 87    @Override
 88    public double salary() {
 89       eturn getBasicSalary();
 90    }
 91    @Override
 92    public String toString() {
 93       return String.format("%s\nBasic Salary: $%,.2f",
 94          super.toString(),getBasicSalary());
 95    }
 96 }
 97  
 98 package org.mano.example;
 99 public class HourlyEmployee extends Employee {
100    protected double wage;
101    protected double hours;
102    public HourlyEmployee(String name, String ssn,
103    double wage, double hours) {
104       super (name, ssn);
105       setWage(wage);
106       setHours(hours);
107    }
108    public double getWage() {
109       return wage;
110    }
111    public void setWage(double wage) {
112       if(wage >= 0.0)
113          this.wage = wage;
114       else
115          throw new IllegalArgumentException("wage " +
116             "must be > 0.0");
117    }
118    public double getHours() {
119       return hours;
120    }
121    public void setHours(double hours) {
122       if(hours >= 0.0)
123          this.hours = hours;
124       else
125          throw new IllegalArgumentException("hours "  +
126             "must be > 0.0");
127    }
128    @Override
129    public double salary() {
130       return getHours() * getWage();
131    }
132    @Override
133    public String toString() {
134       return String.format("%s\nWage: $%,
135          .2f\nHours worked: %,.2f",
136          super.toString(),getWage(),getHours());
137    }
138 }
139  
140 package org.mano.example;
141 public class CommissionEmployee extends Employee {
142    protected double sales;
143    protected double commission;
144    public CommissionEmployee(String name, String ssn,
145          double sales, double commission) {
146       super(name, ssn);
147       setSales(sales);
148       setCommission(commission);
149    }
150    public double getSales() {
151       return sales;
152    }
153    public void setSales(double sales) {
154       if(sales >=0.0)
155          this.sales = sales;
156       else
157          throw new IllegalArgumentException("Sales " +
158             "must be >= 0.0");
159    }
160    public double getCommission() {
161       return commission;
162    }
163    public void setCommission(double commission) {
164       if(commission > 0.0 && commission < 1.0)
165          this.commission = commission;
166       else
167          throw new IllegalArgumentException("Commission " +
168             "must be between 0.0 and 1.0");
169    }
170    @Override
171    public double salary() {
172       return getCommission() * getSales();
173    }
174    @Override
175    public String toString() {
176       return String.format("%s\nSales: %,
177          .2f\nCommission: %,.2f",
178          super.toString(),getSales(),getCommission());
179    }
180 }

 

Interface Polymorphism

The polymorphism of the interface is very similar to the previous example, except that the polymorphism rules here are based on the specification specified by the Java interface.The interface name can be used as a reference variable, just as we did with the class name above.It references any object of any class that implements the interface.This is an example.

 1 package org.mano.example;
 2 public interface Player {
 3    public enum STATUS{PLAY,PAUSE,STOP};
 4    public void play();
 5    public void stop();
 6    public void pause();
 7 }
 8  
 9 package org.mano.example;
10 public class VideoPlayer implements Player {
11    private STATUS currentStatus = STATUS.STOP;
12    @Override
13    public void play() {
14       if(currentStatus == STATUS.STOP ||
15             currentStatus == STATUS.PAUSE) {
16          currentStatus = STATUS.PLAY;
17          System.out.println("Playing Video...");
18       }
19       else
20          System.out.println("I am ON playing man!");
21    }
22    @Override
23    public voidstop() {
24       if(currentStatus == STATUS.PLAY ||
25             currentStatus == STATUS.PAUSE) {
26          currentStatus = STATUS.STOP;
27          System.out.println("Video play stopped.");
28       }
29       else
30          System.out.println("Do you want me to go fishing?");
31    }
32    @Override
33    public void pause() {
34       if(currentStatus == STATUS.PLAY) {
35          currentStatus = STATUS.PAUSE;
36          System.out.println("Video play paused.");
37       }
38       else
39          System.out.println("I'm a statue. You froze me
40             already!");
41       }
42    }
43  
44 package org.mano.example;
45 public class AudioPlayer implements Player {
46    private STATUS currentStatus = STATUS.STOP;
47    @Override
48    public void play() {
49       if(currentStatus == STATUS.STOP ||
50             currentStatus == STATUS.PAUSE) {
51          currentStatus = STATUS.PLAY;
52          System.out.println("Playing Audio...");
53       }
54       else
55          System.out.println("I am ON playing man!");
56    }
57    @Override
58    public void stop() {
59       if(currentStatus == STATUS.PLAY ||
60             currentStatus == STATUS.PAUSE) {
61          currentStatus = STATUS.STOP;
62          System.out.println("Audio play stopped.");
63       }
64       else
65          System.out.println("Do you want me to go fishing?");
66    }
67    @Override
68    public void pause() {
69       if(currentStatus == STATUS.PLAY) {
70          currentStatus = STATUS.PAUSE;
71          System.out.println("Audio play paused.");
72       }
73       else
74          System.out.println("I'm a statue. You froze me
75             already!");
76       }
77    }
78  
79 package org.mano.example;
80 public class PlayerApp {
81    public static void main(String[] args) {
82       Player player= new VideoPlayer();
83       player.play();
84       player.pause();
85       player.stop();
86       player= new AudioPlayer();
87       player.play();
88       player.pause();
89       player.stop();
90    }
91 }

 

Note that in PlayerApp, we have used the interface Player to declare object reference variables.A reference variable, player, can reference any object of any class that implements the Player interface.To prove this, we use the same player variable here to reference the VideoPlayer object and the AudioPlayer object.The method invoked by the runtime is specific to the class object it references.The relationship between the class implementing the interface and the interface itself is parent-child, as we see in the polymorphic example with inheritance.It is also an is-arelationship and forms the basis of polymorphism.

summary

The difference between polymorphisms through class inheritance or through interfaces is a matter of choice.In fact, the difference is in understanding the properties and characteristics of classes and interfaces.Apart from understanding its nature, there are no strict rules to define when to use it.This is beyond the scope of this article.However, in polymorphism, this idea is both appropriate and capable of doing what we want to do with them.That's it.Stripping cocoons and detailing the structure of those things--Excellent Lessons

Topics: Java Programming less