Overloading and Overriding are two important concepts in object-oriented programming in Java , but they serve different purposes and behave differently.

1.Overloading (Compile-Time Polymorphism)

Definition:

Overloading occurs when multiple methods in the same class share the same name but differ in their parameters (type, number, or both). It is also known as compile-time polymorphism or static polymorphism because the method call is resolved at compile time.

Example:

class Calculator {

    // Method overloading based on parameter types

    public int add(int a, int b) {

        return a + b;

    }

    public double add(double a, double b) {

        return a + b;

    }

    // Method overloading based on the number of parameters

    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("Sum of two ints: " + calc.add(5, 10));          




// Output: 15

        System.out.println("Sum of two doubles: " + calc.add(5.5, 10.2));  

 // Output: 15.7

        System.out.println("Sum of three ints: " + calc.add(1, 2, 3));     

 // Output: 6

    }

}

Output:

Sum of two ints: 15

Sum of two doubles: 15.7

Sum of three ints: 6

Advantages:

  • Increases readability by using the same method name for similar functionalities.
  • Promotes code reusability by allowing different operations using the same method name with different parameters.

Uses:

Method overloading is used when functions logically represent similar operations but require different input parameters, such as:

  • System.out.println() (different data types: int, char, String).
  • Mathematical operations that need to handle different data types (e.g., add, subtract methods with int, double, float).

2.Overriding (Run-Time Polymorphism)

Definition:

Overriding occurs when a subclass provides a specific implementation for a method that is already defined in its parent class. The method in the subclass must have the same name, return type, and parameters as the one in the parent class. It is also known as run-time polymorphism or dynamic polymorphism because the method call is resolved at runtime.

Example:

class Animal {

    // Method to be overridden

    public void sound() {

        System.out.println("Animal makes a sound");

    }

}




class Dog extends Animal {

    // Overriding the parent class method

    @Override

    public void sound() {

        System.out.println("Dog barks");

    }

}




class Cat extends Animal {

    // Overriding the parent class method

    @Override

    public void sound() {

        System.out.println("Cat meows");

    }

}




public class Main {

    public static void main(String[] args) {

        Animal a1 = new Dog();

        Animal a2 = new Cat();

        a1.sound();  // Output: Dog barks

        a2.sound();  // Output: Cat meows

    }

}

Output:

Dog barks

Cat meows

Advantages:

  • Achieves run-time polymorphism, allowing the program to decide which method to invoke based on the actual object, not its reference type.
  • Helps implement specific behavior for subclasses while keeping a consistent method signature with the parent class.

Uses:

Overriding is commonly used in inheritance to define a specific behavior in a subclass, such as:

  • In a graphical user interface (GUI) framework, a parent class may define a draw() method, and subclasses such as Circle, Rectangle, or Triangle may override it to provide their specific drawing behavior.
  • In frameworks and libraries where methods are intended to be overridden by the user of the framework (e.g., Servlet lifecycle methods).