Understanding Polymorphism in Java

Polymorphism in Java allows a single entity, such as a method, to take multiple forms. This is a key aspect of object-oriented programming, enhancing code flexibility and reusability. The two primary forms of polymorphism in Java are method overloading and method overriding.

Method Overloading (Compile-Time Polymorphism)

Method overloading occurs when two or more methods in the same class have the same name but different parameters (in number, type, or both). This allows a method to perform different functions based on the input parameters. It is resolved at compile-time, hence known as compile-time polymorphism.

Example of Method Overloading:

public class Calculator {

    // Method to add two integers
    public int add(int a, int b) {
        return a + b;
    }

    // Overloaded method to add three integers
    public int add(int a, int b, int c) {
        return a + b + c;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println(calc.add(10, 20)); // Calls first add method
        System.out.println(calc.add(10, 20, 30)); // Calls overloaded add method
    }
}

In this example, the Calculator class has two versions of the add method: one that adds two integers and another that adds three integers. The compiler determines which method to call based on the number of arguments.

Method Overriding (Runtime Polymorphism)

Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. This allows a subclass to define a behavior specific to it, which is different from the superclass. The method to be executed is determined at runtime based on the object type, which is why it’s called runtime polymorphism.

Example of Method Overriding:

public class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

public class Dog extends Animal {
    
    // Overriding the sound method
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog();
        myAnimal.sound(); // Outputs "Dog barks"
    }
}

In this example, the sound method in the Dog class overrides the sound method defined in the Animal superclass. When an object of type Dog is treated as an Animal and the sound() method is invoked, the overridden method in Dog is executed, displaying “Dog barks”.

Polymorphism and Inheritance at Work in Java

Example: Animals and Their Sounds

Consider a simple example with a superclass Animal and its subclasses Dog and Cat. Each subclass will override a method from Animal to exhibit polymorphic behavior.

// Superclass
public class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

// Subclass 1
public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

// Subclass 2
public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

// Main class to demonstrate polymorphism
public class Main {
    public static void main(String[] args) {
        Animal myAnimal;

        // Dog instance treated as an Animal
        myAnimal = new Dog();
        myAnimal.makeSound(); // Outputs "Dog barks"

        // Cat instance treated as an Animal
        myAnimal = new Cat();
        myAnimal.makeSound(); // Outputs "Cat meows"
    }
}

Explanation

  • The Animal class has a method makeSound().
  • The Dog and Cat classes extend Animal and override the makeSound() method.
  • In the Main class, we declare a variable myAnimal of type Animal. We then instantiate Dog and Cat objects, but treat them as Animal objects. This is where polymorphism is at play.
  • When we call myAnimal.makeSound(), the version of the method that gets executed depends on the actual object type (Dog or Cat), not the reference type (Animal).