Polymorphism in java

Polymorphism is one of the fundamental concepts in object-oriented programming. It refers to the ability of an object to take many forms. In Java, polymorphism is achieved through method overriding and method overloading.

Method Overriding:

Method overriding is a feature that allows a subclass to provide its own implementation of a method that is already defined in its superclass. The method in the subclass must have the same name, return type, and parameters as the method in the superclass. When the method is called on an object of the subclass, the subclass's implementation is invoked instead of the superclass's implementation.

Let's see an example of method overriding in Java.

class Animal {
  public void sound() {
    System.out.println("The animal makes a sound");
  }
}
class Dog extends Animal {
  public void sound() {
    System.out.println("The dog barks");
  }
}
public class TestDog {
  public static void main(String args[]) {
    Animal a = new Animal();
    Animal d = new Dog();
    a.sound();
    d.sound();
  }
}

In the above example, we have defined two classes Animal and Dog. The Animal class has a method sound(), which prints a message that an animal makes a sound. The Dog class extends the Animal class and overrides the sound() method with its own implementation.

In the main() method, we create objects of the Animal and Dog classes and call their sound() methods. When the sound() method is called on the Animal object, it prints the message defined in the Animal class. When the sound() method is called on the Dog object, it prints the message defined in the Dog class.

The output of the program will be:

The animal makes a sound
The dog barks

Method Overloading:

Method overloading is a feature that allows a class to have multiple methods with the same name but different parameters. The methods must have different parameter lists, which can include different types or different numbers of parameters. When the method is called, the appropriate version of the method is selected based on the number and types of the arguments passed to it.

Let's see an example of method overloading in Java.

class Calculator {
  public int add(int a, int b) {
    return a + b;
  }
  public double add(double a, double b) {
    return a + b;
  }
}
public class TestCalculator {
  public static void main(String args[]) {
    Calculator c = new Calculator();
    int sum1 = c.add(2, 3);
    double sum2 = c.add(2.5, 3.5);
    System.out.println("Sum of integers: " + sum1);
    System.out.println("Sum of doubles: " + sum2);
  }
}

In the above example, we have defined a class Calculator with two methods add() that have the same name but different parameter lists. One method takes two integers as arguments, and the other method takes two doubles as arguments.

In the main() method, we create an object of the Calculator class and call both versions of the add() method with different arguments. The appropriate version of the method is selected based on the types of the arguments.

The output of the program will be:

Sum of integers: 5
Sum of doubles: 6.0

Thus, we have seen how polymorphism can be achieved through method overriding and method overloading in Java.