Polymorphism in Java

Polymorphism in Java denotes an object’s capacity to take several forms. Simply put, polymorphism in Java enables us to accomplish the same function in various ways. In Java, any object passing more than one IS-A test is polymorphic. As a result of passing the IS-A test for their type and the class Object, all Java objects are polymorphic. Polymorphism in Java is divided into two kinds: compile-time polymorphism and runtime polymorphism.

This article also covers two types of polymorphism in Java: compile-time polymorphism and runtime polymorphism, Java polymorphism examples, method overloading, method overriding, and why polymorphism is helpful in Java.

Polymorphism is a characteristic of the object-oriented programming language Java that means you can do the same thing in multiple ways. Polymorphism in Java allows for various implementations in the technical realm by defining a single interface.

How does polymorphism affect you?

The derivation of polymorphism is from two Greek words: poly and morphism. “Poly” stands for “many,” and “morphs” stands for “forms.” As a result, polymorphism denotes the existence of numerous variations. As a result, polymorphism is one of the most critical elements of Object-Oriented Programming.

In Java, what is polymorphism?

Polymorphism is a Java task that executes the same activity in multiple ways. Languages that do not enable polymorphism are called “Object-Based Languages” instead of “Object-Oriented Languages.” Ada, for example, is one of these languages. Java is an Object-Oriented Language because it enables polymorphism.

Polymorphism develops when there is an inheritance or numerous classes connected. In Java, inheritance is a powerful feature. Inheritance allows one class to have access to another’s properties and characteristics. In Java, polymorphism will enable us to use these inherited attributes for various purposes. As a result, we can perform the same activity in multiple ways.

Polymorphism in the Real World

A person might have a variety of relationships with different persons. A man can be a father, a son, a brother, and a friend all at once, i.e., she can act in different ways in different contexts.

The human body, on the other hand, comprises various organs. The heart is in charge of blood flow, the lungs control breathing, the brain controls cognitive activity, and the kidneys are in charge of excretion. As a result, we have a standard method function that behaves differently based on the body organ.

Example of Polymorphism in Java

The function “area()” is part of the “Shapes” superclass. “Triangle,” “circle,” “Rectangle,” and other subclasses of “Shapes” are examples. Each subclass has a different method for computing areas. Subclasses can utilize the “area()” method to determine the area’s formula for that shape using Inheritance and Polymorphism.

class Shapes {
  public void area() {
    System.out.println("This is the formula for the area of ");
  }
}
class Triangle extends Shapes {
  public void area() {
    System.out.println("Triangle is ½ * base * height ");
  }
}
class Circle extends Shapes {
  public void area() {
    System.out.println("Circle is 3.14 * radius * radius ");
  }
}
class Main {
  public static void main(String[] args) {
    Shapes theShape = new Shapes();  // Create a Shapes object
    Shapes theTriangle = new Triangle();  // Create a Triangle object
    Shapes theCircle = new Circle();  // Create a Circle object
    theShape.area();
    theCircle.area();
    theTriangle.area();
    theShape.area();
  }
}

Polymorphism Types

Polymorphism can be done in Java using two alternative methods:

  • Overloading and
  • Overriding of Methods

In Java, what is method overloading?

Method overloading creates numerous methods with the same name in the same class, each performing a different function. When a class has multiple ways with the same name, this is known as method overloading.

An example of method overloading in Java

class Shapes {
  public void area() {
    System.out.println("Find area ");
  }
 
public void area(double b, double h) {
    System.out.println("Triangle area="+0.5*b*h);
  }
public void area(int l, int b) {
    System.out.println("Rectangle area="+l*b);
  }
public void area(int r) {
    System.out.println("Circle area = "+3.14*r*r);
  }
 
 
}
 
class Main {
  public static void main(String[] args) {
    Shapes theShape = new Shapes();  // Create a Shapes object
     
    theShape.area();
    theShape.area(5);
    theShape.area(6,2);
    theShape.area(6.0,1.2);
     
  }
}

What is method overriding in Java?

When a subclass or a child class has the same method as the parent class, this is known as method overriding. In Java, an example of method overriding is:

class Vehicle{  
  //defining a method  
  void run(){System.out.println("Vehicle is moving");}  
}  
//Creating a child class  
class Bus extends Vehicle{  
  //definition of the parent's method  
  void run(){System.out.println("The bus is running Safely");}  
  
  public static void main(String args[]){  
  Bus theCar = new Bus();//creating object  
  theCar.run();//calling method  
  }  
}  

Polymorphism in Java can also be divided into two types:

  • Polymorphism in Static/Compile-Time
  • Dynamic/Runtime Polymorphism is a type of polymorphism that occurs in real-time.

In Java, what is Compile-Time Polymorphism?

Static polymorphism is another name for compile-time polymorphism in Java. In addition, the method call is resolved at compile time. Method Overloading is used to achieve compile-time polymorphism. Operator Overloading is used to accomplish this form of polymorphism.

Java, on the other hand, does not support Operator Overloading.

When a class contains numerous methods with the same name, but the number, types, and order of parameters and the return type of the methods are different, this is known as method overloading. Java permits the user to use the same name for many functions as long as the type and number of parameters are distinguished.

In Java, what is an example of compile-time polymorphism?

Using subtract(), we’ll conduct addition in Java and learn about compile-time polymorphism.

package staticPolymorphism;
public class Addition
{
void sum(int x, int y)
{
int w = x+y;
System.out.println(" Addition of two numbers :" +w); }
void sum(int x, int y, int z)
{
int w = x+y+z;
System.out.println(" Addition of three numbers :" +w); }
public static void main(String[] args)
{
Addition obj = new Addition();
obj.sum (150,210);
obj.sum(165, 200, 142);
}
}

The sum() method is responsible for overloading two types via distinct parameters in this program. It is the basic concept of compile-time polymorphism in Java, where many methods with the same name are used to perform different activities.

What is Java Runtime Polymorphism?

Dynamic Binding or Dynamic Method Dispatch are other terms for runtime polymorphism in Java. In this approach, the call to an overridden method is resolved dynamically at runtime rather than at build time. Method Overriding can be used to produce Runtime polymorphism.

When a child or subclass has a method with the same name, parameters, and return type as the parent or superclass, the child or subclass overrides the superclass’s function. To put it another way, if a subclass defines a method that already exists in the superclass, that function in the base class is said to be overridden.

It’s also worth noting that runtime polymorphism is only possible with functions, not data members.

Overriding is accomplished by using a superclass reference variable. The object determines the method invoked method that the reference variable refers to. Upcasting is another term for this. On the off chance that the parent class’s reference variable refers to the child class’s object, upcasting occurs. As an example,

class MainClass{}

class SecondaryClass extends MainClass{}  

MainClass a=new SecondaryClass(); //upcasting

In Java, examples of runtime polymorphism

1st example:

In this example, we’ll make one superclass Human and three subclasses, Herbivores, Carnivores, and Omnivores. Subclasses extend and override the superclass’s eat() function. The parent class’s reference variable, i.e., Human class, will call the eat() method.
The method at the base class is invoked at runtime because it references the base class object and the base class method overrides the superclass method. It is runtime polymorphism because the Java Virtual Machine, or JVM, determines method invocation rather than the compiler.

class Human{  
  void eat(){
System.out.println("Humans Eat");
}  
}  
class herbivores extends Human{  
  void eat(){
System.out.println("Herbivores Eat Plants");
}
  }
class omnivores extends Human{  
  void eat(){
System.out.println("Omnivores Eat Plants and meat");
}
  }
class carnivores extends Human{  
  void eat(){
System.out.println("Carnivores Eat meat");
}
  }
class main{
  public static void main(String args[]){
    Human A = new Human();
    Human h = new herbivores(); //upcasting  
    Human o = new omnivores(); //upcasting  
    Human c = new carnivores(); //upcasting  
    A.eat();
    h.eat();
    o.eat();  
    c.eat();  
   
  }  
}  


2nd Example :

In this example, we will make one superclass Computer and three subclasses, Laptop, Desktop, and Supercomputer. The superclass is extended by subclasses, which override the location() and famousfor() methods.

The Parent class, i.e., Computer, will call the shortForm() and famousfor() methods. The method at the base class is invoked at runtime because it references the base class object and the base class method overrides the superclass method. The latter is runtime polymorphism since method invocation is determined by the Java Virtual Machine, or JVM, rather than the compiler.

class Computer{  
  void shortForm(){
System.out.println("Shortform is:");
}  
void famousfor(){
System.out.println("Famous for:");
}  
 
}  
class Laptop extends Computer {  
  void shortForm(){
System.out.println("Laptop is LP");
}  
void famousfor(){
System.out.println("It is Famous for its Portability");
}  
  }
class Desktop extends Computer {  
  void shortForm(){
System.out.println("Desktop is DK");
}  
void famousfor(){
System.out.println("It is famous for its Flexibility");
}  
  }
class SuperComputer extends Computer {  
  void shortForm(){
System.out.println("SuperComputer is SC");
}  
void famousfor(){
System.out.println("It is Famous for its Speed");
}  
  }
class main{
  public static void main(String args[]){
    Computer comp = new Computer();
    Computer laptop = new Laptop();
 
    Computer desktop = new Desktop();
 
    Computer superComp = new SuperComputer();
 
comp.shortForm();
comp.famousfor();
 
laptop.shortForm();
laptop.famousfor();
 
desktop.shortForm();
desktop.famousfor();
 
superComp.shortForm();
superComp.famousfor();
  }  
}  

Example: run-time polymorphism In Java

We’ll make two classes. Car and SalonCar, where the SalonCar class extends the Car class and overrides the run() method.

class Car
{
void run()
{
System.out.println(" running");
}
}
class SalonCar extends Car
{
void run();
{
System.out.println(" running at 180km/hr");
}
public static void main(String args[])
{
Car sCar = new SalonCar();
sCar.run();
}
}

Example: Another Java run-time polymorphism

Let’s see if data members are used in achieving runtime polymorphism.

class car
{
int speedlimit = 125;
}
class Innova extends Car
{
int speedlimit = 135;
public static void main(String args[])
{
car obj = new innova();
System.out.println(obj.speedlimit);
}

It indicates that we won’t create Runtime polymorphism using data members. In other words, a method, not the data members, is overridden.

Example: Multilevel inheritance and runtime polymorphism

class grandfather
{
void swim()
{
System.out.println(" Swimming");
}
}
class father extends grandfather
{
void swim()
{
System.out.println(" Swimming in river");
}
}
class son extends father
{
void swim()
{
System.out.println(" Swimming in pool");
}
public static void main(String args[])
{
grandfather f1,f2,f3;
f1 =new grandfather();
f2 = new father();
f3 = new son();
f1.swim();
f2.swim();
f3.swim():
}
}

Example: runtime polymorphism with hierarchical inheritance

class Animal
{
public void Sound()
{
System.out.println("Different sounds of animal"); }
}
class buffalo extends soundAnimal
{
public void Sound()
{
System.out.println("The buffalo sound- gho,gho"); }
}
class snake extends soundAnimal
{
public void Sound()
{
System.out.println("The snake sound- his,his"); }
}
class tiger extends soundAnimal
{
public void Sound()
{
System.out.println("The tiger sounds- roooo, rooo"); }
}
public class Animal Main
{
public static void main(String[] args)
{
Animal animal = new Animal(); 
Animal buffalo = new buffalo();
Animal snake = new snake();
Animal tiger = new tiger();
animal.Sound();
buffalo.Sound();
snake.Sound();
tiger.Sound();
}
}

Exploring polymorphic Subtypes

Subtype simply indicates that a subtype can be a subtype of another type. Does it seem complicated?

Let’s look at an example to assist you in understanding:

If we need to draw random shapes, we can create a’ shape’ class with a draw() method. We’ll add an array of type ‘shape’ whose components contain references to ‘shape’ subclass references by overriding draw() with other subclasses such as circle, square, rectangle, trapezium, and so on by overriding draw() with other subclasses such as circle, square, rectangle, trapezium, and so on.

When we call draw() the next time, all the shapes’ draw() methods are called.

Upcasting and late binding are standard features of this Subtype polymorphism. Upcasting is casting up the inheritance tree from a subtype to a supertype.

Late binding is used to call non-final instance methods. In other words, a compiler should not perform any argument checks, type checks, method calls, or anything else and should instead rely on the runtime to do so.

In programming, what is polymorphism?

Polymorphism uses a single symbol to represent numerous different kinds of programming.

What are Polymorphism Variables, and how do they work?

During the execution of a program, a polymorphic variable is defined as a variable that can hold values of several types.

What is the purpose of polymorphism in Java?

In Java, polymorphism allows you to build a method that can handle various functions with the same name. Polymorphism can also help us achieve consistency in our programming.

Polymorphism’s Benefits in Java

  • It allows the code to be reused.
  • The written, tested and implemented classes are reused several times. Furthermore, it saves the coder a significant amount of time. In addition, the code is changed without affecting the original code.
  • Multiple data values are stored in a single variable.
  • You can alter the value of an inherited variable from the superclass into the subclass. That is doable without affecting the superclass or any other subclasses.
  • It is easier for the programmer to debug code with fewer lines of code.

Polymorphism Characteristics

Aside from Method Overloading and Method Overriding, polymorphism has several more qualities.
They are as follows:

  • Internal Operator overloading
  • Coercion
  • Polymorphic Variables or Parameters

Coercion

The implicit conversion of one type of object into a new object of a different kind is the subject of coercion. It is also done automatically to avoid type problems in the code.

Programming languages such as C, Java, and others support the conversion of values from a given type to another.
There are two sorts of data type conversions: implicit and explicit.

Implicit type conversion is sometimes known as coercion because it occurs automatically in the program. For example, if one operand is an integer and the other is a float, the compiler implicitly changes the integer to a float value to prevent a type error.

class coercion {
 
  public static void main(String[] args) {
    Double area = 3.14*5*7;
System.out.println(area);
String stringOne = "Codeunderscored ";
int a=15;
String result = stringOne+a;
System.out.println(result);
 
  }
}

Overloaded internal operators

Operator Overloading occurs when an operator or symbol operates in more than one manner depending on the input context or operand type. It is a feature of static polymorphism.

Although Java does not provide user-defined operator overloading like C++, which allows the user to specify how an operator behaves for different operands, there are a few cases where Java overloads operators internally.

The principle of operator overloading is to use the operator of your choosing. As a result, depending on the requirements, an operator symbol or method name can be used as a ‘user-defined’ type.

For instance, ‘+’ can be used to add two or more numbers (of the same data type) or to concatenate two or more strings. You can use + for both addition and concatenation.

Consider the following scenario:

class coercion {
 
  public static void main(String[] args) {
     
String stringOne = "code";
String stringTwo = "underscored";
int a=50;
int b=80;
 
System.out.println(stringOne+stringTwo);
System.out.println(a+b);
 
  }
}

For logical and bitwise operations, operators like! &, and | are also in the overloaded position.
In both of these circumstances, the operator’s interpretation is determined by the type of argument.

Polymorphic Parameters or Variables

Polymorphic variables are represented by an object or instance variables in Java. The latter is because a class’s object variables can have an IS-A relationship with their subclasses and classes.

The Polymorphic Variable can hold multiple sorts of values simultaneously during execution. A field name is associated with several types. On the other hand, a method name can be associated with different parameters and return types according to parametric polymorphism.

Consider the following scenario:

class Shape
{
public void display()
{
System.out.println("A Shape.");
}
}
class Triangle extends Shape
{
public void display()
{
System.out.println("I am a triangle.");
}
}
class Main{
public static void main(String[] args)
{
Shape obj;
obj = new Shape();
obj.display();
obj = new Triangle();
obj.display();
}
}

The obj object is a polymorphic variable in this case. It is because the superclass’s identical object refers to both the parent (Shape) and the child (Shape) (Triangle).

Polymorphism’s Challenges

Polymorphism has several benefits, but it also has a few drawbacks.

  • When it comes to implementation, polymorphism is quite tricky.
  • It has the effect of making the code less readable.
  • It also causes some major real-time performance concerns.

Identifying Types During Downcasting

Casting to a child type or casting a common type to an individual type is called downcasting. As a result, if we need to access or understand the behavior of subtypes, we use downcasting.

Example,

It is an example of a hierarchical structure.

Food> Fruits> Mango, Apple

Apple and Mango are two subclasses in this case. We narrow the type of objects by downcasting, which means we reduce common type to individual type.

Fruits fruit = new Apple();

Casting Apple

Apple = (Apple) Fruits;

We’re converting a common type into an individual type and a superclass into a subclass, which isn’t feasible in Java directly. We inform the compiler what the object’s runtime type is explicit.

Problem with a brittle base class

The problem of a fragile base class is nothing more than a primary design issue. When a parent class is misdesigned, a subclass of a superclass may use the superclass in unexpected ways. Even if all of the criteria are met, the fragility of inheritance will result in broken codes.

This architectural challenge is the fragile base class problem in object-oriented programming systems and languages. The cause for the fragile base problem is that the base class’s developer is unaware of the subclass’s design. This problem still hasn’t been solved.

Conclusion

Polymorphism, which means “many forms,” happens when multiple classes are related via inheritance. Inheritance allows us to inherit characteristics and methods from another class, as discussed earlier. Polymorphism employs these techniques for a variety of purposes. It enables us to carry out a single activity in various ways.

One of the most significant characteristics of Object-Oriented Programming is polymorphism.

Polymorphism permits us to carry out the same activity in multiple ways. Polymorphism, in other terms, allows you to specify a single interface with various implementations. The words “poly” and “morphs” both imply “many,” therefore, it means “many forms.”

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *