Polymorphism is one of the core concepts of Object-Oriented Programming (OOP) in Java. It allows objects to be treated as instances of their parent class rather than their actual class. This enables a single interface to represent different underlying forms (data types).

Key Concepts of Polymorphism

  1. Method Overloading: This is a compile-time polymorphism where multiple methods have the same name but different parameters.
  2. Method Overriding: This is a runtime polymorphism where a subclass provides a specific implementation of a method that is already defined in its superclass.
  3. Polymorphic Variables: Variables that can hold references to objects of different types at different times during the execution of a program.

Method Overloading

Method overloading allows a class to have more than one method with the same name, as long as their parameter lists are different.

Example of Method Overloading

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

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

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

    public static void main(String[] args) {
        MathOperations math = new MathOperations();
        System.out.println(math.add(2, 3)); // Output: 5
        System.out.println(math.add(2, 3, 4)); // Output: 9
        System.out.println(math.add(2.5, 3.5)); // Output: 6.0
    }
}

Explanation

  • The add method is overloaded with different parameter lists.
  • The correct method is chosen at compile time based on the arguments passed.

Method Overriding

Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass.

Example of Method Overriding

class Animal {
    // Method to be overridden
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

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 myDog = new Dog();
        myDog.sound(); // Output: Dog barks
    }
}

Explanation

  • The sound method in the Dog class overrides the sound method in the Animal class.
  • The @Override annotation is used to indicate that a method is being overridden.
  • The method to be executed is determined at runtime based on the object type.

Polymorphic Variables

Polymorphic variables can refer to objects of different types at different times.

Example of Polymorphic Variables

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

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

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

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

        myAnimal = new Dog();
        myAnimal.sound(); // Output: Dog barks

        myAnimal = new Cat();
        myAnimal.sound(); // Output: Cat meows
    }
}

Explanation

  • The variable myAnimal is of type Animal but can refer to objects of type Dog or Cat.
  • The method to be executed is determined at runtime based on the actual object type.

Practical Exercise

Exercise

Create a class hierarchy where Vehicle is the superclass and Car and Bike are subclasses. Override a method move in both subclasses to print specific messages.

Solution

class Vehicle {
    public void move() {
        System.out.println("Vehicle is moving");
    }
}

class Car extends Vehicle {
    @Override
    public void move() {
        System.out.println("Car is moving");
    }
}

class Bike extends Vehicle {
    @Override
    public void move() {
        System.out.println("Bike is moving");
    }
}

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

        myVehicle = new Car();
        myVehicle.move(); // Output: Car is moving

        myVehicle = new Bike();
        myVehicle.move(); // Output: Bike is moving
    }
}

Explanation

  • The move method is overridden in both Car and Bike classes.
  • The myVehicle variable can refer to either a Car or a Bike object, demonstrating polymorphism.

Common Mistakes and Tips

  • Common Mistake: Forgetting to use the @Override annotation when overriding methods. This can lead to subtle bugs if the method signature does not match exactly.
  • Tip: Always use the @Override annotation to ensure that you are correctly overriding a method.

Conclusion

Polymorphism is a powerful feature in Java that allows for flexible and reusable code. By understanding and utilizing method overloading, method overriding, and polymorphic variables, you can write more dynamic and maintainable programs. In the next topic, we will delve into encapsulation, another fundamental concept of OOP.

Java Programming Course

Module 1: Introduction to Java

Module 2: Control Flow

Module 3: Object-Oriented Programming

Module 4: Advanced Object-Oriented Programming

Module 5: Data Structures and Collections

Module 6: Exception Handling

Module 7: File I/O

Module 8: Multithreading and Concurrency

Module 9: Networking

Module 10: Advanced Topics

Module 11: Java Frameworks and Libraries

Module 12: Building Real-World Applications

© Copyright 2024. All rights reserved