java polymorphism with example

Java Polymorphism with Example

In this tutorial, we will learn about polymorphism and its implementation with the help of examples.

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

What is Polymorphism in Java?

Polymorphism in Java refers to an object’s ability to take multiple forms. To put it another way, polymorphism in Java allows us to perform the same action in multiple ways. Polymorphism is a feature of Java’s object-oriented programming language that allows a single task to be completed in multiple ways.

  • In object-oriented programming, polymorphism is a crucial concept. It simply means that there are multiple forms.
  • That is, in different scenarios, the same entity (method, operator, or object) can perform different operations.
  • Polymorphism is a Java concept that allows us to perform a single action in multiple ways. Polymorphism is made up of two Greek words: poly and morphism. The words “poly” and “morphs” mean “many” and “forms,” respectively. As a result, polymorphism denotes the presence of multiple forms.
  • Polymorphism in Java is divided into two types: compile-time polymorphism and runtime polymorphism. Polymorphism in Java is achieved through method overloading and overriding.

Example: Polymorphism

class Polygon {

  // method to render a shape
  public void render() {
    System.out.println("Rendering Polygon");
  }
}

class Square extends Polygon {

  // renders Square
  public void render() {
    System.out.println("Rendering Square");
  }
}

class Circle extends Polygon {

  // renders circle
  public void render() {
    System.out.println("Rendering Circle");
  }
}

class Main {
  public static void main(String[] args) {
    
    // create an object of Square
    Square s1 = new Square();
    s1.render();

    // create an object of Circle
    Circle c1 = new Circle();
    c1.render();
  }
}

Output:

Rendering Square
Rendering Circle

We’ve created a superclass, Polygon, and two subclasses, Square and Circle, in the example above. Take note of the render() method’s use.

The render() method’s main purpose is to render the shape. The process of rendering a square, on the other hand, differs from that of rendering a circle.

As a result, the render() method behaves differently depending on the class. Or, to put it another way, render() is polymorphic.

Runtime Polymorphism in Java

Dynamic Binding or Dynamic Method Dispatch are other terms for runtime polymorphism in Java. The call to an overridden method is resolved dynamically at runtime rather than at compile-time in this process. Method Overriding is used to achieve runtime polymorphism.

Method When a child or subclass has a method with the same name, parameters, and return type as the parent or superclass, that function overrides the parent’s or 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 worth noting that runtime polymorphism is only possible with functions, not data members.

Overriding is accomplished by using a superclass reference variable. The object referred to by the reference variable is used to determine which method should be called. Upcasting is another term for this.

  • When the parent class’s reference variable refers to the child class’s object, upcasting is used. Consider the following scenario:
class A{}
class B extends A{}
A a=new B(); //upcasting

Examples of Runtime Polymorphism in Java

We’re going to make two classes in this example: Bike and Honda. Honda is an extension of the Bike class that overrides the run() method. The Parent class’s reference variable is used to call the run method. The subclass method is called at runtime because it refers to the subclass object and overrides the Parent class method.

Runtime polymorphism refers to the fact that method invocation is determined by the JVM rather than the compiler.

class Bike{  
  void run(){System.out.println("running");}  
}  
class Honda extends Bike{  
  void run(){System.out.println("Running with 40km");}  
  
  public static void main(String args[]){  
    Bike h = new Honda();//upcasting  
    h.run();  
  }  
}  
Running with 40km

What is Compile-Time Polymorphism in Java?

Static polymorphism is another name for compile-time polymorphism in Java. The call to the method is resolved at compile time in this process. Method Overloading is used to achieve compile-time polymorphism. Operator Overloading can also be used to achieve this type of polymorphism. Java, on the other hand, does not support Operator Overloading.

When a class has multiple methods with the same name, but the number, types, and order of parameters, as well as the return type of the methods, is different, this is known as method overloading. Java allows the user to use the same name for multiple functions as long as the type and number of parameters can be distinguished.

public class Main {
   public static void main(String args[]) {
      CompileTimePloymorphism obj = new CompileTimePloymorphism();
      obj.display();
      obj.display("DevelopersDome");
   }
}
class CompileTimePloymorphism {
   void display() {
      System.out.println("Display without parameter");
   }
   void display(String x) {
      System.out.println("Display with parameter" + x);
   }
}

What is the difference between compile-time and run-time polymorphism?

One of the most important OOPs concepts is polymorphism. It is a concept that allows us to perform a single task in a variety of ways. Polymorphism is divided into two types: compile-time polymorphism and run-time polymorphism.

Compile-time polymorphism is exampled by method overloading, while run-time polymorphism is exampled by method overriding.

Sr. No.PointCompile-time polymorphismRuntime polymorphism
1BasicCompile-time polymorphism:  Binding occurs at compile-time, which is referred to as polymorphism.Run-time polymorphism, in which we know which method will be invoked at run-time.
2Static/Dynamic
Binding
Static binding can be used to accomplish this.Dynamic binding can be used to accomplish this.
3InheritanceInheritance is not involvedInheritance is involved
4ExampleCompile-time polymorphism is demonstrated by method overloading.Runtime polymorphism is demonstrated by method overriding.

Examples of Polymorphism real Life

An individual can have a variety of relationships with various people. A woman can be a mother, a daughter, a sister, and a friend all at the same time, implying that she exhibits different behaviors in different situations.

The human body is made up of various organs. The heart is in charge of blood flow, the lungs are in charge of breathing, the brain is in charge of cognitive activity, and the kidneys are in charge of excretion. As a result, we have a standard method function that differs depending on the organ of the body.

We can achieve polymorphism in Java using the following ways:

  1. Method Overriding
  2. Method Overloading
  3. Operator Overloading

Java Method Overriding

Method overriding is defined as the process by which a subclass or child class has the same method as the parent class.

If the same method is present in both the superclass and the subclass during inheritance in Java. The method in the subclass then overrides the method in the superclass. This is known as method overriding.

  • In this case, the same method will carry out one operation in the superclass and another in the subclass. As an example:
class Language {
  public void displayInfo() {
    System.out.println("Kotlin Language");
  }
}

class Java extends Language {
  @Override
  public void displayInfo() {
    System.out.println("Java Language");
  }
}

class Main {
  public static void main(String[] args) {

    // create an object of Java class
    Java j = new Java();
    j.displayInfo();

    // create an object of Language class
    Language l = new Language();
    l.displayInfo();
  }
}

Output:

Java Language
Kotlin Language

In the preceding example, we created a superclass called Language and a subclass called Java. The method displayInfo() is present in both Language and Java in this case.

The displayInfo() function is used to print the information. It does, however, print different information in Language and Java.

Java Method Overloading

Method overloading is defined as the process of creating multiple methods with the same name in the same class, each of which works in a different way. Method overloading occurs when a class contains multiple methods with the same name.

class Shapes {
  public void area() {
    System.out.println("Find Area ");
  }
public void area(int r) {
    System.out.println("Circle area = "+3.14*r*r);
  }
 
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);
  }
 
 
}
 
class Main {
  public static void main(String[] args) {
    Shapes s = new Shapes();  // Create a Shapes object
     
    s.area();
    s.area(5);
    s.area(6.0,1.2);
    s.area(7,2);
     
  }
}

Output:

Find Area
Circle area = 78.5
Triangle area=3.60
Rectangle area=14

Java Operator Overloading

Some Java operators behave differently depending on the operand. As an example:

  • The + operator can perform numeric addition as well as string concatenation, and operators such as &, |, and! can perform logical and bitwise operations.
  • Let’s take a look at how we can achieve polymorphism with operator overloading.

To join two entities, use the + operator. In Java, however, the + operator performs two operations.

  1. When the symbol + is used with numbers (both integers and floating-point numbers), it performs mathematical addition. As an example:
int a = 5;
int b = 6;
// + with numbers
int sum = a + b; // Output = 11

2. When we use the + operator with strings, it performs string concatenation (join two strings). For instance:

int a = 5;
int b = 6;
// + with numbers
int sum = a + b; // Output = 11

In this case, we can see that the + operator in Java is overloaded to perform two operations: addition and concatenation.

Polymorphic Variables

If a variable refers to different values under different conditions, it is said to be polymorphic.

In Java, object variables (instance variables) represent polymorphic variable behaviour. This is due to the fact that object variables of a class can refer to both objects of the class and objects of its subclasses.

Polymorphic Example

class ProgrammingLanguage {
  public void display() {
    System.out.println("Java Programming Language.");
  }
}

class Java extends ProgrammingLanguage {
  @Override
  public void display() {
    System.out.println("Object-Oriented Programming Language.");
  }
}

class Main {
  public static void main(String[] args) {

    // declare an object variable
    ProgrammingLanguage p;

    // create object of ProgrammingLanguage
    p = new ProgrammingLanguage();
    p.display();

    // create object of Java class
    p = new Java();
    p.display();
  }
}

Output:

Java Programming Language.
Object-Oriented Programming Language.
  • We created an object variable pl of the ProgrammingLanguage class in the preceding example. Pl is a polymorphic variable in this case. Because of this,
  • Pl refers to the object of the ProgrammingLanguage class in the statement pl = new ProgrammingLanguage().
    Furthermore, in the statement pl = new Java(), pl refers to the Java class’s object.
    In Java, this is an example of upcasting.

Polymorphic Subtypes

Subtype basically means that a subtype can serve as the subtype of another type, sounds complicated?

Let us illustrate this with an example.

  • Assuming we need to draw some arbitrary shapes, we can create a class called’shape’ that includes a draw() method. We will introduce an array of type’shape’ whose elements store references will refer to’shape’ subclass references by overriding draw() with other subclasses such as circle, square, rectangle, trapezium, and so on. When we call draw() again, all shapes’ draw () methods will be called.
  • This Subtype polymorphism is characterised by upcasting and late binding. Upcasting is a casting that occurs when you cast up the inheritance hierarchy from a subtype to a supertype. The operator is involved in these types of casting no cast.
  • We use late binding to call non-final instance methods. In short, a compiler should not perform any argument checks, type checks, method calls, or anything else, and should instead leave everything to the runtime.

The Advantages of Polymorphism in Java

  • It allows the code to be reused. Classes that have been written, tested, and implemented can be reused several times. This, in turn, saves the coder a significant amount of time. Furthermore, the code can be modified without affecting the original code.
  • Multiple data values can be stored in a single variable. A variable inherited from the superclass into the subclass can have its value changed without affecting the variable’s value in the superclass or any other subclasses.
  • Debugging the code becomes easier for the programmer with fewer lines of code.

Polymorphism Characteristics

Other than Method Overloading and Method Overriding, polymorphism has many other characteristics. They are as follows:

  1. Coercion
  2. Internal Operator Overloading
  3. Polymorphic Variables or Parameters

Coercion

Coercion is concerned with the implicit conversion of one type of object into a new object of a different type. This is done automatically to avoid typing mistakes in the code.

  • Value conversion from one data type to another is supported by programming languages such as C, Java, and others. There are two kinds of data type conversions: implicit and explicit.
  • The programme performs implicit type conversion automatically, and this type of conversion is also known as coercion.
  • To avoid type errors, for example, if one operand is an integer and the other is a float, the compiler implicitly converts the integer to a float value.
class coercion {
 
  public static void main(String[] args) {
    Double area = 3.14*8*8;
System.out.println(area);
String s = "Sagar";
int x=10;
String word = s+x;
System.out.println(word);
 
  }
}

Output:

200.96
Sagar10

Internal Operator Overloading

Operator Overloading occurs when an operator or symbol behaves in more than one way depending on the input context or operand type. It is a feature of static polymorphism. Although Java does not support user-defined operator overloading in the same way that C++ does, where the user can define how an operator works for different operands, there are a few cases where Java internally overloads operators.

  • The concept of operator overloading is the use of the operator of your choice. As needed, an operator symbol or method name can be used as a user-defined type.
  • For example, the ‘+’ operator can be used to perform addition of numbers (of the same data type) or concatenation of two or more strings.
  • When it comes to +, it can be used for both addition and concatenation.
class coercion {
 
  public static void main(String[] args) {
     
String s = "DevelopersDome";
String s1 = "DevelopersDome1";
int x=50;
int y=10;
 
System.out.println(s+s1);
System.out.println(x+y);
 
  }
}

Output:

DevelopersDomeDevelopersDome1
60

Similarly, for logical and bitwise operations, operators such as! &, and | are overloaded. The type of argument determines how the operator is interpreted in both of these cases.

polymorphism in java, runtime polymorphism in java, types of polymorphism in java, compile time polymorphism in java,

Polymorphic Variables or Parameters

Polymorphic variables are represented in Java by object or instance variables. This is due to the fact that any class’s object variables can have an IS-A relationship with their own classes and subclasses.

  • A polymorphic variable is one that can hold different types of values at the same time during execution.
  • Parametric polymorphism specifies that a field name can be associated with different types during class declaration, and a method name can be associated with different parameters and return types.
class Shape
{
public void display()
{
System.out.println("Sagar Paliwal");
}
}
class Triangle extends Shape
{
public void display()
{
System.out.println("DevelopersDome.");
}
}
class Main{
public static void main(String[] args)
{
Shape obj;
obj = new Shape();
obj.display();
obj = new Triangle();
obj.display();
}
}

Output:

SagarPaliwal
DevelopersDome

The obj object is a polymorphic variable in this case. This is due to the superclass’s same object referring to both the parent (Shape) and child classes (Triangle).

Issues with Polymorphism

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

  • Polymorphism is difficult to implement because it reduces the readability of the code.
  • Polymorphism causes serious real-time performance issues.

Example: Java Runtime Polymorphism with Multilevel Inheritance

class Animal{  
void eat(){System.out.println(" i am eating");}  
}  
class Dog extends Animal{  
void eat(){System.out.println("i am eating fruit");}  
}  
class BabyDog extends Dog{  
void eat(){System.out.println(" i am drinking milk");}  
public static void main(String args[]){  
Animal x,y,z;  
x=new Animal();  
y=new Dog();  
z=new BabyDog();  
x.eat();  
y.eat();  
z.eat();  
}  
}  

Output:

I am eating
I am eating fruit
I am drinking Milk

You may like:

Java Inheritance with Example | Types of inheritance

Java final Keyword with Example

Not Equal Example in Java

Hope this article will guide you to recognize all about the Java Polymorphism with example that you needed and still if you have any problem or queries regarding this, post them in the comments section and we will be glad to assist you.

This Post Has 6 Comments

Leave a Reply