Polymorphism

The word "polymorphism" means "many forms". It comes from Greek word "poly" (means many) and "morphos" (means form).

For examples, in chemistry, carbon exhibits polymorphism because it can be found in more than one form: graphite and diamond.

Each of the form has its own distinct properties. The term homonym means "a word the same as another in sound and spelling but with different meaning."

The term bear could be a verb (to carry a burden) or it could be a noun (a large, hairy mammal). One can distinguish between the two usages through the use of context clues.

Polymorphism Technically :

In an Object Oriented Programming language like java, the term polymorphism refers to the ability of an object to take different forms. An object acts or reacts differently in response to different messages/object passed. Messages can be passed through methods.

Polymorphism is one of the greatest feature of object oriented programming and java itself. It makes our code simple, extensible and maintainable.

Types of Polymorphism

In java polymorphism has been categorized into two types.

  • Static Polymorphism
  • Dynamic Polymorphism

Static Polymorphism

Static Polymorphism also called as compile time polymorphism or early binding, is when the behavior of an object is decided at the time of compilation. This type of polymorphism is implemented in java by using a concept called method overloading.

Dynamic Polymorphism

Dynamic Polymorphism also called as run time polymorphism or late binding, is when the behavior of and object is decided at run time. This type of polymorphism is implemented in java by using a concept called method overriding.

Method Overloading

In object oriented programming the behavior of an object is represented by method. The objects with common behaviors belong to a class.

A class defines methods which will be referred by all its objects (instances). Now let us think of a simple example a list employees with their employee_id, names, and department.

Sometimes we need to display records of all employee, sometimes on the basis of employee_id and sometimes on the basis of the name of the employee.

For the above example, we need to create three different methods with three different name for performing different operation for the same problem displaying employee record. This would be done but the programmer need to remember all three different names when he needs to display the employee record for different situation.

Wouldn't it be easy to remember only one method name for any of the three situation? Yes it would be.

The answer to the above problem is method overloading. Method overloading in java is the concept which allows us to define more than one method with same name but different signature in a class and change the behavior of all the overloaded methods.

The signature of the method include three things:

  • Number of parameter
  • Type of parameter
  • Sequence of parameter

For a method to be overloaded method names must be same but the signature must be different in either one of the above way.

Return type of the method is not included in the signature it might be different or same. The decision of calling a method is taken at compile time.

The compiler looks at the method signature (No-of parameter, type of parameter or sequence of parameter) and decides which method to invoke for a particular method call at compile time. This is why it is called as static or compile time polymorphism.

The best example of overloaded method that we can take is the System.out.println(); method which can print int, String, char, float doubles. That means the println(); method is an overloaded method of a built-in class PrintStream.

Now let us define overloaded methods for the problem discussed earlier for displaying employee’s record.


class Employee {
	public void display() {
		//code to display all employee records  
	}
	public void display(int empid) {
		//code to display employee record by employee id 
	}
	public void display(String ename) {
		//code to display employee record by employee name  
	}
}

In the above example, display() is an overloaded method which has three forms one without parameter display (), one with an int parameter display(int empid) and last one with a String parameter display(String ename)

When an instance calls the display method with no argument the body of the display(); method is executed. When passed one int type argument the body of display(int empid). And when passed one String type argument the body of display(String ename); is executed.

class Employee {
	public void display() {
		System.out.println("Display All Employee Records");
	}
	public void display(int empid) {
		System.out.println("Display Employee Records with Employee ID" + empid);
	}
	public void display(String ename) {
		System.out.println("Display Employee Records with Employee Name" + ename);
	}
	public static void main(String ar[]) {
		Employee e = new Employee();
		e.display(); // will display all employees record   
		e.display(100); //will display employee record with employee id 100   e.display("John"); // will display employee record with employee name john 
	}
}

In the above example, the signature of methods differs in number of parameter or type of parameter. Sequence of parameters is used when methods take two or more parameters with different types.

For example, there are two methods to display employee records. One method display on the basis of employee id and department name whereas another method displays on the basis of employee id and designation.

Considering employee id is of int type and designation and department are of String type.

So the overloaded method display can be as follows


void display(int empid, String department) {
	//code to display employee’s record with given employee id and department
}
void display(String designation, int empid) {
	//code to display employee’s record with given employee id and designation 
}
void display(int empid, String department) {
	//code to display employee’s record with given employee id and department
}
void display(String designation, int empid) {
	//code to display employee’s record with given employee id and designation 
}

Before learning dynamic polymorphism and the concept of method overriding we must first understand Inheritance.

Method Overriding

When a class "B" inherits another class "A" where "A" is the super class and "B" is the sub class. Class "B" as the subclass of class "A" has access to all non-private methods of class "A".

However class "B" might not want to use the methods defined by "A" in the same manner. That is, class "B" may use the methods provided by "A" in some other way. In this situation method overriding become handy.

For example:
There is a Car class which has a defined method called drive() with the steps for driving the Car. Another class called RacingCar inheriting Car class, has access to the drive() method but there might be different steps to drive a RacingCar.

Method overriding is the feature supported by java in which a method of the superclass with the same name, return type and signature but with different method body is defined in the subclass.

In a simple word we can say: "Redefining a method of the superclass in the subclass" is called method overriding. When a method of the superclass is not redefined by the subclass, the default implementation is taken. But with the help of method overriding a subclass can have specific implementation for each method of the superclass.

Whenever we talk about method overriding it is with reference of parent-child relationship among the classes.

Mind that constructors cannot be overridden as they are not inherited. Similarly, a static method cannot be overridden as it is associated with class instead of objects and have a single copy for the class. Example:


class Car {
	public void drive() {
		System.out.println("Steps to drive a car");
	}
}
class RacingCar extends Car {
	/* Overriding the drive(); 
method of the Car class. Overriding with @override notation is a good programming practice.  */
	@override public void drive() {
		System.out.println("Steps to drive a racing car");
	}
}
public class MainClass {
	public static viod main(String ar[]) {
		Car c = new Car();
		c.drive(); // output: Steps to drive a car   
		RachingCar rc = new RacingCar();
		rc.drive(); // output: Steps to drive a Racing car.  
	}
}

In the above example, the output of drive() method is depending upon the object being used if it is of Car class the drive() method of Car class is invoked and if it is of RacingCar class the drive() method of RacingCar class is invoked.

The memory for the object is allocated at runtime and response of a method is decided at runtime that is why method overriding is the concept to implement dynamic polymorphism.

Note that the @override notation is not mandatory but using the same is a good programming practice. Because if we are overriding a method without @override notation and misspelling the method name or differing the signature. It would create a new method for the subclass instead of overriding.

However using @override notation before overriding method will mark it as an error when misspelled. Therefore prevent us from making errors.

Let’s understand method overriding with a live example.

Problem Statement
Consider a scenario of various types of employees (temporary and permanent) in an organization. Both types of employee’s salary is calculated with various elements such as basic salary, DA, TA and HRA.

The temporary employee’s salary is calculated as basic salary + TA whereas permanent employee’s salary is calculated as basic salary + DA + TA + HRA.


Solution
class Employee {
	public double basic,
	da,
	ta,
	hra;
	public double calcSalary() {
		return 0;
	}
}
class Temporary extends Employee {@override
	public double calcSalary() {
		Return basic + ta;
	}
}
class Permanent extends Employee {@override
	public double calcSalary() {
		Return basic + da + ta + hra;
	}
}
Public class MainClass {
	Public static void main(Stirng ar[]) {
		/* An object of a subclass can be assigned to reference variable of class up in the inheritance hierarchy. This is known as dynamic binding.*/
		Employee e = new Temporary();
		//setting the values for instance variables for object of class Temporary.   e.basic=5000;  
		e.ta = 1000;
		// calling the overridden method calSalary() in class Temporary.   
		double netSalary = e.calSalary();
		System.out.println("Net salary of temporary Employee is" + netSalary);
	}
}

The output of the above code will be:


Net salary of temporary Employee is 6000
The final keyword, super Keyword and super() method 

The final keyword

While working in an object oriented programming language like java there might be a situation where we do not want a particular variable to be changed or a method definition of is changed by some of the child classes or might be we don’t a class to be inherited for security reasons.

The final keyword is a modifier in java which can be used with variables, methods and classes for protecting it with unwanted changes.

The final keyword can be applied with the variables, a final variable that has no value it is called blank final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final variable can be static also which will be initialized in the static block only.

If a variable is made final it can be assigned only once. Reassigning value to a final variable will result in an error.

Example:


class Circle {
	public final double pi = 3.14;
	public Circle() {
		//re assigning value to a final variable will give an error.  
		Pi = 3.146;
	}
	public static void main(String ar[]) {
		Circle c = new Circle();
	}
}

Output:
the program will result an error because the pi is declared as final and it has already been assigned a value 3.14 at the time declaration it cannot be reassigned a value anywhere in the program.

A final variable can also be made static (e.g. public final static double pi=3.14). It does make sense as a final variable will retain its same value for each instance of the class. There is no need to allocate separate memory for each instance of the class.

The final method

A final method cannot be overridden. Means that if a method in the superclass has been declared as final it cannot be redefined in the subclass.


class Shape {
	public final double pi() {
		return 3.14;
	}
}
class Circle extends Shape {
	/* overriding a final method pi will result an error.*/
	@override
	public double pi() {
		return 3.146;
	}
}

The final Class, A final class cannot be inherited. A final class is always the last class in the inheritance hierarchy. Inheriting a final class will result in an error. In java String is a static final class.


final class A {}
class B extends A {}

Above code will result in an error.

The super Keyword

The super is a reference variable that is used to refer immediate parent class object. Whenever we create the instance of subclass, an instance of parent class is created implicitly i.e. referred by super reference variable.

Think of an example we have an overridden method of the superclass in the subclass. By creating the instance of the subclass we can call the method of the subclass at the same time we want to call the method of the superclass. How can we do so?

The answer is super keyword which refers to the instance of the superclass and distinguishes the instance of the superclass with subclass.

Let’s understand by an example.


class Account {
	public void showBalance() {
		System.out.println("Showing Account Balance");
	}
}
class SavingAccount extends Account {
	public void showBalance() {
		//calling the parent class method here by using super keyword   super.showBalance();   
		System.out.println("Showing Balance for Saving Account");
	}
}

public class MainClass {
	public static void main(String ar[]) {
		SavingAccount sa = new SavingAccount();
		sa.showBalance();
	}
}

Output:


Showing Account Balance. 
Showing Balance for Saving Account.

The super() method is used for calling the constructor of the superclass. As we know the default constructor (constructor with zero parameters) is called implicitly when instance of the subclass is created.

But if we have overloaded the constructors in the parent class, they cannot be called implicitly. There comes the use of super() method. The call to the super(); with appropriate number, type and sequence of parameters would cause the appropriate constructor of the superclass to be called. But is must be the first line of statement within the constructor of the subclass.


class Vehicle {
	public Vehicle() {
		System.out.println("Vehicle is created");
	}
}
class Bike extends Vehicle {
	public Bike() {
		super(); //will invoke parent class constructor        
		System.out.println("Bike is created");
	}
	public static void main(String args[]) {
		Bike b = new Bike();
	}
}

Output:


Vehicle is created  Bike is created 

About Author

Myself KarthiQ, I am the author of this blog, I know ways to write a good article but some how I donot have the skills to make it to reach people, would you like help me to reach more people By sharing this Article in the social media.

Share this Article Facebook
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Recent Addition

new tutorial Protractor Online Training : We have closed registration for training

Please do email to chercher.tech@gmail.com for any queries

If you already registered then please do check your email for the Webex link for the training starting from 15th Nov 2018
 
Join My Facebook Group
Join Group