Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

  • polymorphism allows a single reference (a superclass or interface) to refer to objects of different subclasses, with specific behavior determined by the actual object type at runtime or compile time.
  • it enables code to work with objects in generalized way while allowing specific implementation to vary.
  • purpose
    • flexibility - write generic code that works with multiple types.
    • extensibility - add new subclasses without modifying existing code.
    • reusability - use a common interface or superclass to handle diverse objects.

types of polymorphism

  • runtime polymorphism - achieved through method overriding, where the method to be called is determined at runtime based on actual object type.
  • compile time polymorphism - achieved using method overloading or operator overloading where method is chosed at compile time based on method signature.

runtime polymorphism

  • achieved through method overriding, where a subclass provides a specific implementation of a method defined in superclass or interface.
  • jvm determines the actual type of object at runtime and invokes the overridden method of subclass, even if the reference type is the superclass or interface.
class Animal {
    void sound() {
        System.out.println("Generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Meow");
    }
}

class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // Superclass reference, Dog object
        Animal animal2 = new Cat(); // Superclass reference, Cat object
        
        animal1.sound(); // Output: Woof (Dog's method called)
        animal2.sound(); // Output: Meow (Cat's method called)
    }
}

compile time polymorphism

  • achieved using method overloading, where multiple methods in the same class have the same name but different parameters lists.
  • the compiler determines which method to call at compile time based on method signature and arguments passed.
class Calculator {
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
}

class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println(calc.add(2, 3));       // Output: 5
        System.out.println(calc.add(2.5, 3.5));   // Output: 6.0
        System.out.println(calc.add(1, 2, 3));    // Output: 6
    }
}

advantages

  • flexibility - write generic code that works with multiple types
  • extensibility - add new subclasses or implementations without modifying existing code
  • maintainability - reduces code duplication by using common interface or superclasses.

limitations

  • performance overhead - runtime polymorphism involves dynamic method dispatch, which is slightly lower than static binding.
  • complexity - overuse of polymorphism can make code harder to understand.
  • downcasting risks - incorrect downcasting can lead to classCastException