Last Updated: 24 December, 2023
Hey guys, In this article, we will explain what polymorphism is in Java and the two different types of it (compile-time polymorphism and run-time polymorphism), along with examples and answers to some frequently asked questions.
Polymorphism is one of the strong core features of object-oriented programming (OOP) that allows us to perform a single action in different ways.
Polymorphism is a combination of the two Greek words Poly and Morphs, where "Ploy" means many and “Morphs” means forms. Therefore, polymorphism means “many forms”.
Real-world Example of Polymorphism:
At the same time, a person can have different characteristics. A man is, at the same time, a father, a husband, a worker, a customer, etc. So the same person possesses different behaviors in various scenarios. An example of this is polymorphism.
Java supports two types of polymorphism:
We can achieve compile-time polymorphism by method overloading and runtime polymorphism by method overriding.
In Java, compile-time polymorphism can be achieved through method overloading, which allows a class to have two or more methods with the same method name but different parameters.
This polymorphism is resolved during compilation time; that's why it's called compile-time polymorphism.
Compile-time polymorphism is also known as static polymorphism in Java.
Overloaded methods must be declared within the same class.
The overloaded method must be different in the argument list (number of parameters, data type of parameters, or order of parameters).
The overloaded method can have the same or a different return type.
Overloaded methods can have different access modifiers (public, private, or protected).
Overloaded methods can throw different exceptions.
Here’s an example of creating an overloaded methods in Java.
Example 1: Method Overloading - By changing the number of parameters
In the above example, the class Addition has three overloaded add() methods, and each method has a different number of int parameters. These methods are called based on their number of parameters. See the output below.
Output
Added two int values: 60
Added three int values: 90
Added four int values: 220
Example 2: Method Overloading - By changing the data types of parameters
Here, the Addition class has three overloaded add methods, and each add method has two parameters, but each method's parameter types are different from each other, so the compiler will call these methods according to their data types at compile time.
Output
Added two int values: 60
Added two float values: 66.25
Added one int and one float value: 110.25
Run-time polymorphism can be achieved through method overriding in Java. Method overriding can be performed only in inheritance, which means we declare the same method in both parent and child classes with the same signature.
"Method overriding" is the process of redefining a method in a child class that is already defined in the parent class. When both parent and child classes have the same method, then that method is said to be the overriding method. The method overriding enables the child class to change the implementation of the method acquired from the parent class according to its requirements.
This polymorphism is resolved during runtime and is achieved through method overriding. It is also known as "dynamic method dispatch."
The overriding method must have the same name, parameter list, and return type as the overridden method.
The overriding method cannot be less accessible than the overridden method (e.g., can't be private if the overridden method is public).
In Java, we cannot achieve method overriding with the following types of methods: Private Methods, Static Methods, Final Methods.
Method overriding is a fundamental concept in many design patterns, such as Template Method and Strategy.
Abstract methods are always overridden in the child class.
Let's understand how to implement method overriding in Java with the help of the given example below.
Example: Method Overriding Implementation in Java
In the above example, the Square class is extending the Shape class and rewriting the draw() method. That means the draw() method is overridden in the child class (Square). When we call the draw() method, only the child class's draw() method is called.
Output
Square class - draw() method
Square class - draw() method
✅ The @Override annotation is a method-level annotation that is used with the overridden method in the child class, but it is not mandatory.
✅ The @Override annotation informs the compiler that the method in the child class is overriding the parent class method.
✅ The overridden method can be called by the child class object or the parent class reference object.
Code Reusability: Polymorphism allows us to write code that can be reused with different objects, saving time and effort.
Flexibility and Dynamism: Polymorphism enables code to adapt to different objects at runtime, making it more flexible and adaptable to change.
Reduced Complexity: Polymorphism simplifies code by allowing us to use the same method name for related actions, improving readability and maintainability.
Reduced Coupling: Polymorphism makes code more modular, which makes it easier to test and modify. It does this by reducing the dependencies between classes.
Extensibility: It is simpler to extend applications when new functionality can be added without changing the old code.
Recommended Reading:
Difference between Method Overloading and Method Overriding
That's all guys, hope this Java article is helpful for you.
Happy Learning... 😀
feedback@javabytechie.com
The following are some frequently asked important interview questions—answers from the Java Prolimorphism.
How to achieve static polymorphism in Java?
In Java, static polymorphism can be achieved by method overloading, which means in the same Java class we write two or more methods with the same method name but a different signature.
This polymorphism is resolved during the compiler time. It is also known as compile-time polymorphism.
How does the Java compiler differentiate between methods in compile-time polymorphism?
During compilation, the Java compiler differentiates multiple methods having the same name by their signatures.
How to achieve run-time polymorphism in Java?
Ans. We can achieve run-time polymorphism using method overriding in Java. Method overriding can be performed only in inheritance (IS-A relationship), which means we declare the same method in both parent and child classes with the same signature.
"Method overriding" is the process of redefining a method in a child class that is already defined in the parent class. When both parent and child classes have the same method, then that method is said to be the overriding method. The method overriding enables the child class to change the implementation of the method acquired from the parent class according to its requirements.
This polymorphism is resolved during runtime and is achieved through method overriding. It is also known as "dynamic method dispatch."
Why is Static binding also called early binding in Java?
The process of static binding is also known as "early binding" because it takes place before the program is actually executed. Static binding is resolved at compilation time by the compiler.
Why is Dynamic binding also called late binding in Java?
The dynamic binding process can also be referred to as "late binding" or "runtime binding" because the binding occurs at run time. In dynamic binding, the compiler doesn’t decide the method to be called.
What is binding in Java?
Ans. Binding in Java refers to the connecting (linking) of a method call to the method body or definition.
There are two types of binding in Java.
What is the difference between Static and Dynamic Binding in Java?
Ans. There are the following differences between static and dynamic binding:
Static Binding | Dynamic Binding |
---|---|
Static binding is resolved at compile time by the compiler. | Dynamic binding is resolved at runtime. |
Static binding can be achieved through method overloading. | Dynamic binding can be achieved through method overriding. |
Private, static, and final methods show static binding because they cannot be overridden. | Except for private, static, and final methods, other methods show dynamic binding because they can be overridden. |
It happens during compilation time, so it is also called "early binding". | As dynamic binding happens during runtime, it is also called "late binding". |
Static binding takes place using normal functions. | Dynamic binding takes place using virtual functions. |
Static binding provides fast execution. | Dynamic binding provides slow execution. |