POLYMORPHISM - Java OOPs Simplified - Part 4
Table of contents
POLYMORPHISM
Polymorphism is one of the 4 major pillars of OOPs. The other three are Inheritance, Abstraction and Encapsulation.
"Polymorphism" is derived from 2 Greek words, where 'poly' means "many" and 'morphs' means "forms", so in turn polymorphism means "many forms".
So in Java, it's the way of performing a task in different ways, i.e., the same object or method can perform different things in different scenarios.
Now, let me take an example to explain it in a much easier way. The most simple and commonly stated example is that of Shapes. Imagine you have a drawing program that can draw different shapes like circles, squares, and triangles. Each shape can be drawn on the screen, but they have their unique ways of drawing.
So let's see how this works in code.
// this is a common Shape interface
interface Shape {
void draw();
}
// Let's create specific shape classes that implement Shape
class Triangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Triangle");
}
}
class Oval implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Oval");
}
}
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class Main {
public static void main(String[] args) {
// Im just creating an array of different shapes
Shape[] shapes = new Shape[3];
shapes[0] = new Triangle();
shapes[1] = new Oval();
shapes[2] = new Rectangle();
// here we are using polymorphism to draw different shapes
for (int i = 0; i < shapes.length; i++) {
Shape shape = shapes[i];
shape.draw();
}
}
}
So if I explain the above example;
So here we have a common interface
Shape
with a methoddraw()
.We create specific shape classes (
Triangle
,Oval
,Rectangle
) that implements theShape
interface and provide their uniquedraw()
implementations.In the
Main
class, we create an array of different shapes, each instantiated as a different type of shape (polymorphism).We use a for loop to call the
draw()
method on each shape, and even though we're using the same method name, each shape draws itself the respective shape based on its specific implementation.
So now you have got an idea about the purpose of Polymorphism. Now let's look at the different ways to achieve this.
Method Overloading
Method Overriding
Method Overloading
In method overloading, we can use the method with the same name but different parameters within a single class. So in one class, you can have many methods with the same name but different types or different numbers of parameters.
It is also called compile time polymorphism because in the compile time java determines which method to be called based on the number or type of arguments used for method calling.
NB: Parameters of a method is also called method signature.
NB: Return type is not considered while we overload a method, which means 2 methods within a class can have the same or different return types.
NB: Minimum number of classes required to overload a method is 1.
Let's now look at a simple example of method overloading in Java.
public class Calculator {
// a method to add two numbers
public int add(int a, int b) {
return a + b;
}
// a method to add three numbers
public int add(int a, int b, int c) {
return a + b + c;
}
// a method to add two double type numbers
public double add(double a, double b) {
return a + b;
}
public static void main(String[] args) {
Calculator c1 = new Calculator();
int result1 = c1.add(7, 11);
int result2 = c2.add(4, 3, 9);
double result3 = c3..add(6.5, 1.9);
System.out.println("method1= " + result1); // output: method1= 18
System.out.println("method2= " + result2); // output: method1= 16
System.out.println("method3= " + result3); // output: method1= 8.4
}
}
In the above example, the class Calculator
used the method with the name add
more than once within the class with different numbers and different types of parameters.
If you look at the method you can see an object with name c1 is created and it is used to invoke the methods. Also, it's very important to note that, you have to send the arguments matching the parameters when we call those methods. If you provide arguments of incorrect type or number it will result in a "compilation error".
But if you look at the return type we have used the same as well as different return types. So it's clear that return type is not important in method overloading.
Method Overriding
In method overriding we can use the method with the same name and the same parameters in different classes. So it allows the child class to provide a specific implementation of a method that is already defined in the parent class.
It is important to note that when the child class overrides the method, it provides a new implementation for that method with the same name, parameter and return type.
It is also an example of rum time polymorphism.
NB: For overriding, we require at least 2 classes.
NB: The child class cannot use more restrictive access modifiers than the parent class, which means if the parent class method is public, then child class method should be either public or protected. It cannot be "private".
NB: The overriding method should have the same method name, parameters and return types.
Now let's have a look at an example of overriding.
class ParentCalculator {
int add(int a, int b) {
return a + b;
}
}
class ChildCalculator extends ParentCalculator {
// Method overriding for add
@Override
int add(int a, int b) {
return a + b + 10; // Adds 10 more than the base class,
// because we can make changes only in this portion.
}
}
public class Main {
public static void main(String[] args) {
ParentCalculator c1 = new ParentCalculator();
ChildCalculator c2 = new ChildCalculator();
int result1 = c1.add(7, 11); // Calls the base class method
int result2 = c2.add(4, 16); // Calls the overridden method
System.out.println("Result1: " + result1); // Result1: 18
System.out.println("Result2: " + result2); // Result2: 30
}
}
In this example, we have a ParentCalculator
class with an add
a method that adds two numbers. The ChildCalculator
class extends ParentCalculator
and overrides the add
a method to add '2' to the result.
When we create instances of ParentCalculator
and ChildCalculator
and call the add
method, you can see how method overriding works.
One of the important questions is that is it possible to override a static method. And the answer is "NO", it's not possible to override a static method as it is bound by a class. Like that we cannot override a main method. Because it's a static method.
So this is how method overloading and method overriding work in Java.
Subscribe to my newsletter
Read articles from J B Sankarlal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by