Last Updated on May 17, 2023 by Prepbytes
IPolymorphism is a key concept in Object-Oriented Programming. Polymorphism is made up of two words: poly and morphs. "Poly" means "many," and "Morphs" means "shapes." Polymorphism, in layman’s terms, is the ability of a message to be expressed in a variety of ways.
What is Polymorphism in Java?
Polymorphism is a concept in computer science and object-oriented programming that refers to the ability of a single function or method to operate on multiple types of data. It is a feature of many programming languages, including Java, that allows the same method or function to be used with different types of data, such as integers, strings, and objects. This allows for code reusability and makes the code more efficient and flexible. Polymorphism in java also allows for a more abstract view of objects and their behaviors and enables late binding, which means that the appropriate method to be called is determined at runtime.
Real-World Example for Better Understanding:
Let’s use a person as an example to better grasp the idea of polymorphism. A person can have several traits at once. He may be an Employee, a citizen, a Father, etc; therefore, the person exhibits various behaviors depending on the circumstance.
TV Remote also exhibits this property of Polymorphism. The same power button can be used for the function of “Switch ON” and “Switch OFF”. This can be interpreted as the power button showing different behavior depending on the situation.
Java Polymorphism Example
Let us understand the concept of polymorphism with an example. Consider the code given below:
// Base Class class Parent { void show(){ System.out.println("Parent's show()"); } } // Inherited class class Child extends Parent { // This method overrides show() of Parent @Override void show() { System.out.println("Child's show()"); } } // Driver class class Main { public static void main(String[] args) { Parent obj1 = new Parent(); obj1.show(); Parent obj2 = new Child(); obj2.show(); } }
Output:
Parent's show()
Child's show()
Explanation:
In the above example, we have declared a base class named “Parent”, and a subclass named “Child” which extends the class “Parent”. The Child class overrides the method show() of the Parent class. Now, in the main method, if the Parent type references the Parent object, then the Parent’s show is executed, but if the Parent type references the Child object, then the Child’s show is executed. This process of executing two different methods is known as Run Time Polymorphism in Java.
Types of Polymorphism in Java
Polymorphism in Java can be divided into two main categories explained below in detail:
1. Compile-time Polymorphism
It is also known as static polymorphism and is achieved through method overloading. Method overloading occurs when a class has multiple methods with the same name but different parameters. At compile-time, the Java compiler determines which method to call based on the number and types of arguments passed in.
Examples of Method Overloading:
-
An example to show the concept of Method Overloading is when we pass a different number of parameters to the same function.
Code:
class Main { //add method with 2 parameters public static int add (int a, int b){ return a+b; } //add method with 3 parameters public static int add(int a, int b, int c){ return a+b+c; } public static void main (String[] args){ int a = 12; int b = 35; int c = 7; int ans1 = add(a, b); int ans2 = add(a, b, c); System.out.println("ans1 is "+ ans1); System.out.println("ans2 is "+ ans2); } }
Output:
ans1 is 47 ans2 is 54
Explanation: In the above example, we have defined the two signatures for the “add()” method, one containing only two parameters and another containing three parameters. When we execute the code the first line will call the function “add(int a, int b)” whereas the second line will call the function “add(int a, int b, int c)”.
-
An example to show the concept of Method Overloading is when we pass different types of parameters to the same function
Code:
class Main { //add method with int parameters public static int add (int a, int b){ return a+b; } //add method with double parameters public static double add(double a, double b){ return a+b; } public static void main (String[] args){ int ans1 = add(5, 4); double ans2 = add(3.5, 7.3); System.out.println("ans1 is "+ ans1); System.out.println("ans2 is "+ ans2); } }
Output:
ans1 is 9 ans2 is 10.8
Explanation: In the above example, we have defined the two signatures for the “add()” method, one containing integer parameters and another containing double datatype parameters. When we execute the code the first line will call the function “add(int a, int b)” whereas the second line will call the function “add(double a, double b)”.
2. Run-time Polymorphism
It is also known as dynamic polymorphism and is achieved through method overriding. Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. At runtime, the Java Virtual Machine (JVM) determines which method to call based on the actual type of the object.
Rules for Method Overriding:
- To implement RunTime Polymorphism in Java, there must be inheritance present between classes.
- We cannot override the Final Methods.
- We cannot override methods declared as Static
- We cannot perform Method overriding on Private Methods.
- The Overriding method must have the same return type as of method declared in the base class
- We cannot Override a Constructor
Both types of polymorphism allow for more flexibility and code reuse in a Java program. The main difference is that the decision of which method to call is made at compile-time for compile-time polymorphism, and at runtime for run-time polymorphism.
Polymorphism Real Time Example
- Let us consider an example of the “Shape” class and its two subclasses namely, “Square” and “Circle” and all three classes having the same method called “draw”.
Code:
class Shape { public void draw() { System.out.println("Drawing a shape"); } } class Circle extends Shape { @Override public void draw() { System.out.println("Drawing a Circle"); } } class Square extends Shape { @Override public void draw() { System.out.println("Drawing a Square"); } } class Main{ public static void main(String args[]){ Shape shape1 = new Circle(); shape1.draw(); Shape shape2 = new Square(); shape2.draw(); Shape shape3 = new Shape(); shape3.draw(); } }
Output:
Drawing a Circle
Drawing a Square
Drawing a shape
Explanation: In this example, the class "Shape" is the superclass that defines the method "draw()" and the classes "Circle" and "Square" are subclasses that override the method "draw()" to provide their own implementation. When the following code is executed, The Java Virtual Machine (JVM) will determine which method to call at runtime based on the actual type of the object. In this case, the first line calls the method "draw()" of the class "Circle" and the second line calls the method "draw()" of the class "Square" and the third line will call the method “draw()” of class Circle.
- Consider the following “Animal” class with the method “speak()”.
Code:
class Animal { public void speak() { System.out.println("Animal can speak"); } } class Dog extends Animal { public void speak() { System.out.println("Dogs bark"); } } class Cat extends Animal { public void speak() { System.out.println("Cat Meows"); } } class Lion extends Animal { public void speak() { System.out.println("Lion Roars"); } } class Main{ public static void main(String args[]){ Animal animal1 = new Dog(); animal1.speak(); Animal animal2 = new Cat(); animal2.speak(); Animal animal3 = new Lion(); animal3.speak(); } }
Output:
Dogs bark
Cat Meows
Lion Roars
Explanation: In this example, the class "Dog", “Cat”, and “Lion” has overridden the method "speak()" of the superclass "Animal" with their own specific implementation
When the above code is executed, the Java Virtual Machine (JVM) will determine at runtime which method to call based on the actual type of the object.
This is how Run Time Polymorphism is achieved in Java using the concept of Method Overriding.
Advantages of Polymorphism in Java
The advantages of polymorphism in Java include:
- Code reusability: Polymorphism in Java allows for the reuse of code, making it more efficient and flexible, which in turn reduces the amount of code that needs to be written and maintained by the programmer.
- Abstraction: Polymorphism allows for a more abstract view of objects and their behaviors, which makes the code more readable and maintainable.
- Late binding: Polymorphism in java enables late binding, which means that the appropriate method to be called is determined at runtime. This allows for more dynamic and flexible code.
- Extensibility: Polymorphism in java allows for the creation of more general and reusable code. This makes it easier to extend and modify the code as the project evolves.
- Interfaces: Polymorphism allows the use of a common interface for multiple types of objects, which can be useful for creating more flexible and maintainable code.
- Generic algorithms: Polymorphism allows for the creation of more generic algorithms and data structures that can operate on multiple types of objects.
- Program to an interface: Polymorphism in java allows the developer to program to an interface rather than an implementation. This makes the code more flexible and less dependent on a specific implementation.
- Easier to test: Because polymorphism allows for a more abstract view of objects, it makes it easier to test the code.
Overall, polymorphism is an important concept in object-oriented programming and Java, as it allows for the creation of more efficient, flexible, and reusable code.
Problems with Polymorphism in Java
Polymorphism is a powerful feature in Java that allows objects of different classes to be treated as objects of a common superclass. However, it also has some disadvantages that should be considered when designing and implementing a program:
- Complexity: Polymorphism can make code more complex, especially when dealing with large numbers of classes and interfaces. It can be difficult to understand the behavior of a program when objects of different classes are treated in the same way.
- Performance: Polymorphism in java can have a performance impact as the program needs to determine the type of the object at runtime before invoking the appropriate method. This can lead to slower execution times, especially in large and complex programs.
- Type safety: Polymorphism in java can compromise type safety as it allows objects of different classes to be treated as objects of a common superclass, leading to a possibility of runtime errors.
- Overriding: Polymorphism allows the methods to be overridden, if not used properly it can lead to unexpected results.
- Debugging: Polymorphism in java can make debugging more difficult as it can be hard to trace the execution of a program through the different classes and methods that are involved.
Overall, polymorphism is a powerful feature of Java that can be used to improve the flexibility and maintainability of a program, but it should be used with caution, especially in large and complex programs. Developers should weigh the advantages and disadvantages of polymorphism when designing and implementing a program and use it in a way that ensures good performance, type safety, and maintainability.
Conclusion
To summarize, we have discussed what is polymorphism in Java, polymorphism in Java refers to an object’s ability to take on multiple forms. It is a fundamental concept in object-oriented programming that allows objects of different classes to be treated as belonging to the same superclass. This allows for the creation of code that can operate on objects of different classes in a consistent and predictable manner. The types of polymorphism in Java are mentioned : compile-time (static) polymorphism and runtime (dynamic) polymorphism. Method overloading is used to achieve compile-time polymorphism. The concept of method overriding is used to achieve runtime polymorphism.
Polymorphism enables code reusability, flexibility, and extensibility by allowing objects of different classes to be treated as a single type. It also allows for more efficient and maintainable code by reducing the need for type-checking and explicit casting.
Frequently Asked Questions (FAQs)
Q1. What is the best example for polymorphism in Java?
Ans. Polymorphism is an OOPs feature that allows us to perform the same action in multiple ways. For example, let’s say we have a class Animal that has a method sound(). Because this is a generic class, we cannot provide implementations such as Roar, Meow, Oink, and so on.
Q2. What are the 2 types of polymorphism in Java?
Ans. Polymorphism in Java can be accomplished in two ways:
- Method Overloading.
- Method Overriding.
Q3. Is overloading static or dynamic?
Ans. Method overloading is a static polymorphism, whereas method overriding is a dynamic polymorphism.
Q4. What is overriding in Java?
Ans. Method overriding occurs in Java when a subclass (child class) contains the same method as the parent class.