logo

Java Polymorphism


Show

Polymorphism is the aptitude of an entity to enlist numerous forms. The mainly ordinary employ of polymorphism in OOP crop up when a parent class position is used to submit to a child class entity.

Any Java entity that container overtakes extra than one IS-A test is believed to be polymorphic. In Java, entire Java entities are polymorphic as any item will bypass the IS-A test for their possess kind and for the class item.

It is significant to identify that the only likely way to the right of entry of an entity is during a position variable. An orientation uneven can be of only one kind. Once announced, the category of a situation variable never be changed.

The position changeable can be moved to other entities if it is not stated concluding. The sort of the orientation changeable would decide the systems that it can appeal to on the object.

An orientation inconsistent can pass on to some object of its affirmed type or several subtypes of its announced type. An orientation changeable can be announced as a class or line type.

Example

Let us look at an example.

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

Now, the Deer class is considered to be polymorphic since this has multiple inheritances. Following are true for the above examples −

  • A Deer IS-A Animal
  • A Deer IS-A Vegetarian
  • A Deer IS-A Deer
  • A Deer IS-A Object

When we apply the reference variable facts to a Deer object reference, the following declarations are legal −

Example

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

All the reference variables d, a, v, o refer to the same Deer object in the heap.

Virtual Methods

In this section, I will show you how the behavior of overridden methods in Java allows you to take advantage of polymorphism when designing your classes.

We previously have conversed technique superseding, where a child class can supersede away in its parent. An overridden technique is hidden in the parent class, and is not raised except the child class utilizes the super keyword in the overriding system.

Example

/* File name : Employee.java */
public class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }

   public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
   }

   public String toString() {
      return name + " " + address + " " + number;
   }

   public String getName() {
      return name;
   }

   public String getAddress() {
      return address;
   }

   public void setAddress(String newAddress) {
      address = newAddress;
   }

   public int getNumber() {
      return number;
   }
}

Now suppose we extend the Employee class as follows:

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary; // Annual salary
   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
   }
   
   public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName()
      + " with salary " + salary);
   }
   
   public double getSalary() {
      return salary;
   }
   
   public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
         salary = newSalary;
      }
   }
   
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

Now, you study the following program carefully and try to determine its output:

/* File name : VirtualDemo.java */
public class VirtualDemo {

   public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");   
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

This will produce the following result:

Output

Constructing an Employee
Constructing an Employee

Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0

Here, we instantiate two Salary objects. One using a Salary reference s, and the other using an Employee reference e.

While invoking s.mailCheck(), the compiler sees mailCheck() in the Salary class at compile-time, and the JVM invokes mailCheck() in the Salary class at run time.

mailCheck() on e is quite different because e is an Employee reference. When the compiler sees e.mailCheck(), the compiler sees the mailCheck() method in the Employee class.

Here, at compile-time, the compiler used mailCheck() in Employee to validate this statement. At run time, however, the JVM invokes mailCheck() in the Salary class.

This performance is submitted to as virtual technique invocation, and these processes are submitted to as practical methods. An override technique is invoked at scuttle time, no subject what data category the reference is that was utilized in the font code at the accumulate time.

Here at Intellinuts, we have created a complete Java tutorial for Beginners to get started in Java.