Polymorphism in OOPs

In object-oriented programming, polymorphism is an interesting concept that enables objects to assume diverse forms and behaviors. It provides software systems with flexibility and adaptability by allowing a single interface to represent multiple underlying implementations. This strong feature makes a program more maintainable overall and encourages the modularization of code. With polymorphism, software developers have access to a variety of possibilities that enable elegant and effective solutions to challenging problems. We cover polymorphism’s definition, types, examples, and benefits in this article on polymorphism in OOPs.

What is Polymorphism?

The ability of any data to be processed in multiple ways is known as polymorphism. The word simply gives away its meaning: morphism means types, and poly implies numerous. One of the key ideas of object-oriented programming languages is polymorphism.

One of the fundamental ideas of object-oriented programming (OOP) is polymorphism, which characterizes circumstances in which something manifests in multiple forms. It refers to the idea in computer science that several object types can be accessed using a single interface. Every kind is capable of offering a self-contained implementation of this interface. Explore various types of Java applications and gain expertise with them.

Important Aspects of Polymorphism

Two types of polymorphism exist in the Object-Oriented Programming (OOPS) language, which are as follows:

  • Compile time, often known as static binding Polymorphism, – eg. ‘Method Overloading’
  • Runtime or Dynamic Binding Polymorphism, – eg. ‘Method Overriding’

Static Polymorphism or Compile Time Polymorphism

Object-oriented programming languages implement static polymorphism by allowing the programmer to implement many methods through a technique called method overloading. Despite the similarity of their names, their specifications differ. The following circumstances favor static polymorphism:

  • Each parameter needs to have its own unique type.
  • There’s a chance the parameters will show up differently.
  • One method’s parameter count should be different from the other method’s.

Example

class Pattern 

{

public void display() 

{

     for (int i = 0; i < 10; i++) 

{

       System.out.print(“*”);

     }

}

public void display(char symbol) 

{

     for (int i = 0; i < 10; i++) 

{

       System.out.print(symbol);

}

}

}

class Main 

{

   public static void main(String[] args) 

{

     Pattern d1 = new Pattern();

d1.display();

     System.out.println(“\n”);

d1.display(‘#’);

   }

}

Suggested Article: Top 15 Facts about Java | Multithreading in Python

Runtime Polymorphism or Dynamic Polymorphism

In dynamic polymorphism, a call to a single overridden method is resolved during program execution. Method overriding is among the most well-known uses of runtime polymorphism. Virtual functions and pointers enable overriding in this process.

One method is declared in a subclass that is contained in a parent class when using method overriding. The child class receives an implementation method. 

The class provides another inherited method with a specification of its own during runtime polymorphism. The parent class object codes are not changed to accomplish this transfer across methods. Check out the object class in Java for a better understanding of this concept.

Example

class Language 

{

   public void displayInfo() 

{

     System.out.println(“Common English Language”);

   }

}

class Java extends Language 

{

   @Override

   public void displayInfo() 

{

     System.out.println(“Java Programming Language”);

   }

}

class Main 

{

   public static void main(String[] args) 

{

Java j1 = new Java();

     j1.displayInfo();

Language l1 = new Language();

     l1.displayInfo();

   }

}

Recommended Read: Learn the important role of Git in DevOps and enhance your skills at SLA.

Types of Polymorphism

In this part, we will look at the various forms of polymorphism in OOP, along with examples that highlight their applications and advantages.

Ad hoc Polymorphism

Ad hoc polymorphism, sometimes referred to as function overloading or method overloading, permits different ways to implement the same method or name depending on the type, quantity, or combination of both. Because it can adapt to different use situations, this kind of polymorphism helps developers create interfaces that are understandable and easy to use. 

For example, take the Calculator class as an example. Its add() method may add many types of operands, including textual, integers, and floating-point numbers. By overloading the add() function, we may gracefully handle a variety of parameter types:

class Calculator:

    def add(self, a, b):

        return a + b

    def add(self, a, b, c):

        return a + b + c

    def add(self, a, b, c, d):

        return a + b + c + d

Also Read: Role of Python in Artificial Intelligence 

Parametric Polymorphism

Programmers can create code that can function on several types of values by utilizing parametric polymorphism, also referred to as generic programming. It ensures type safety and permits code reuse by isolating common functions. For example: In many programming languages, such as Java and C++, generic classes can offer parametric polymorphism. Examine the subsequent illustration of a generic class named Container that is capable of storing any value:

class Container<T> 

{

     private T value;

     public T getValue() 

{

         return value;

     }

     public void setValue(T value) 

{

         this.value = value;

     }

}

The core implementation is the same, but we can create instances of Container for different types, like ContainerInteger> or ContainerString>, by using the generic type argument T. Read to learn about jump statements in Python.

Inclusion Polymorphism

Under inclusion polymorphism, also known as subtype polymorphism or runtime polymorphism, objects belonging to different classes might be regarded as instances of the same superclass. This polymorphic behavior makes it possible to implement dynamic method dispatch, where the appropriate method implementation is determined at runtime by the actual object type. 

For instance: Think about the following situation: We have two derived classes, Circle and Rectangle, from a base class called Shape. Each derived class overrides the ‘calculateArea()’ function to calculate the area based on the object’s geometry. Nonetheless, a reference to the basic class Shape can be used to store and manipulate them:

class Shape 

{

     public double calculateArea() 

{

         return 0;

     }

}

class Circle extends Shape 

{

     private double radius;

public double calculateArea() 

{

         return Math.PI * radius * radius;

     }

}

class Rectangle extends Shape 

{

     private double length;

     private double width;

public double calculateArea() 

{

         return length * width;

     }

}

Also Read: Reason behind the bright future of Python

Advantages of Polymorphism

Three major advantages of polymorphism in OOPs increase the effectiveness and maintainability of software systems:

Code Reusability: By recognizing objects of multiple classes as belonging to a common superclass, polymorphism allows developers to reuse existing code. As a result, code bases become more effective, compact modular architecture is encouraged and code duplication is decreased.

Flexibility and Extensibility: Systems can be made flexible and extendable by using polymorphic code, which can adjust to various data types and behaviors. By taking advantage of runtime polymorphism, developers can create new features without changing the existing code, increasing scalability and reducing the likelihood of introducing issues.

Simplified Development: By abstracting away particular characteristics, polymorphism simplifies the development of complicated systems. By concentrating on common interfaces and behaviors, developers can create systems that are simpler to comprehend, test, and maintain.

Polymorphic Collections: The ability to handle objects of various kinds is a key feature of polymorphism, which is utilized in the design of data structures such as arrays, lists, and maps. This facilitates the creation of dynamic data structures that can adjust to shifting demands.

Also Read: Trending Software Courses for non-IT Graduates

Bottom Line

Polymorphism in OOPs facilitates code reuse by allowing classes and code to be designed, tested, and implemented once. You can store variables of several data types (float, double, long, int, etc.) under a single variable name. It facilitates the creation of strong, intricate abstractions from simpler ones. Enroll in our top software courses to learn more about polymorphism in OOPs and develop your programming skills.