Inheritance and Polymorphism

Dive deeper into inheritance, its benefits, and different types (single, multiple, multilevel). Understand polymorphism (method overriding and overloading) and its applications.


Method Overloading in Java

What is Method Overloading?

Method overloading is a powerful feature in Java that allows a class to have multiple methods with the same name but with different parameters. The Java compiler differentiates between these methods based on the number, type, and order of the parameters. This is a form of compile-time polymorphism, also known as static polymorphism.

Detailed Explanation: Compile-Time Polymorphism

Compile-time polymorphism means that the specific method to be called is determined at compile time, not at runtime. The compiler uses the argument list of the method call to figure out which overloaded method to execute. This process is called static binding or early binding. Because the decision is made at compile time, it enhances the performance of the program. It's faster than dynamic binding (used with method overriding, a form of runtime polymorphism) since the method call resolution is already done when the program executes.

The key criteria for method overloading are:

  • Different Number of Parameters: The methods can have different numbers of arguments.
  • Different Types of Parameters: The methods can have the same number of arguments, but the arguments must be of different data types.
  • Different Order of Parameters: The methods can have the same number and types of arguments, but the order of the arguments must be different.

Note: Return type alone is not sufficient for overloading a method. The compiler needs to be able to distinguish between the methods based on the parameters.

Example in Java

Here's a Java example demonstrating method overloading:

 public class Calculator {

    // 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 doubles
    public double add(double a, double b) {
        return a + b;
    }

    // Method to add an integer and a double (in that order)
    public double add(int a, double b) {
        return a + b;
    }

    // Method to add a double and an integer (in that order)
     public double add(double a, int b) {
        return a + b;
    }


    public static void main(String[] args) {
        Calculator calc = new Calculator();

        System.out.println("Sum of 2 integers: " + calc.add(5, 10));
        System.out.println("Sum of 3 integers: " + calc.add(5, 10, 15));
        System.out.println("Sum of 2 doubles: " + calc.add(2.5, 3.5));
        System.out.println("Sum of int and double (int, double): " + calc.add(5, 3.5));
        System.out.println("Sum of int and double (double, int): " + calc.add(2.5, 5));

    }
} 

In this example, the Calculator class has four methods named add. Each add method takes different parameters: two integers, three integers, two doubles, an integer and a double, and a double and an integer. The compiler determines which add method to call based on the arguments passed to it.

When the main method calls calc.add(5, 10), the compiler selects the add(int a, int b) method because the arguments are two integers. Similarly, calc.add(2.5, 3.5) calls the add(double a, double b) method because the arguments are two doubles. This illustrates how method overloading works and how the compiler resolves the correct method to call at compile time.