Overloading

Introduction

Method Overloading allows multiple methods with the same name but different parameters in the same class.


Method Overloading

Rules:

  • Same method name
  • Different parameters (number, type, or order)
  • Return type can be same or different
  • In the same class

Syntax:

class ClassName {
    returnType methodName(type1 param1) { }
    returnType methodName(type2 param1) { }
    returnType methodName(type1 param1, type2 param2) { }
}

Basic Example

class Calculator {
    // Method 1: Two int parameters
    int add(int a, int b) {
        return a + b;
    }

    // Method 2: Three int parameters
    int add(int a, int b, int c) {
        return a + b + c;
    }

    // Method 3: Two double parameters
    double add(double a, double b) {
        return a + b;
    }
}

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

        System.out.println(calc.add(10, 20));           // Calls method 1
        System.out.println(calc.add(10, 20, 30));       // Calls method 2
        System.out.println(calc.add(10.5, 20.5));       // Calls method 3
    }
}

Ways to Overload

1. Different Number of Parameters:

class Example {
    void display(int a) {
        System.out.println("One parameter: " + a);
    }

    void display(int a, int b) {
        System.out.println("Two parameters: " + a + ", " + b);
    }
}

2. Different Type of Parameters:

class Example {
    void display(int a) {
        System.out.println("Integer: " + a);
    }

    void display(String a) {
        System.out.println("String: " + a);
    }

    void display(double a) {
        System.out.println("Double: " + a);
    }
}

3. Different Order of Parameters:

class Example {
    void display(int a, String b) {
        System.out.println(a + ", " + b);
    }

    void display(String a, int b) {
        System.out.println(a + ", " + b);
    }
}

Complete Example

class Print {
    void show(int x) {
        System.out.println("Integer: " + x);
    }

    void show(double x) {
        System.out.println("Double: " + x);
    }

    void show(String x) {
        System.out.println("String: " + x);
    }

    void show(int x, int y) {
        System.out.println("Two integers: " + x + ", " + y);
    }
}

public class Main {
    public static void main(String[] args) {
        Print p = new Print();

        p.show(10);           // Integer: 10
        p.show(10.5);         // Double: 10.5
        p.show("Hello");      // String: Hello
        p.show(5, 10);        // Two integers: 5, 10
    }
}

Constructor Overloading

class Student {
    String name;
    int rollNo;
    double marks;

    // Constructor 1: No parameters
    Student() {
        name = "Unknown";
        rollNo = 0;
        marks = 0.0;
    }

    // Constructor 2: Two parameters
    Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
        this.marks = 0.0;
    }

    // Constructor 3: Three parameters
    Student(String name, int rollNo, double marks) {
        this.name = name;
        this.rollNo = rollNo;
        this.marks = marks;
    }

    void display() {
        System.out.println(name + ", " + rollNo + ", " + marks);
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student("John", 101);
        Student s3 = new Student("Alice", 102, 85.5);

        s1.display();
        s2.display();
        s3.display();
    }
}

Return Type in Overloading

Return type alone CANNOT differentiate overloaded methods.

Invalid:

class Wrong {
    int method(int x) {
        return x;
    }

    double method(int x) {  // ❌ Error: Same signature
        return x;
    }
}

Valid:

class Correct {
    int method(int x) {
        return x;
    }

    double method(double x) {  // ✓ Different parameter type
        return x;
    }
}

Varargs and Overloading

class Example {
    void display(int x) {
        System.out.println("Single int: " + x);
    }

    void display(int... x) {  // Varargs
        System.out.println("Varargs: " + x.length + " arguments");
    }
}

public class Main {
    public static void main(String[] args) {
        Example obj = new Example();

        obj.display(10);         // Calls single int version
        obj.display(10, 20, 30); // Calls varargs version
    }
}

Type Promotion in Overloading

Java automatically promotes smaller types to larger types.

class Example {
    void display(int x) {
        System.out.println("int: " + x);
    }

    void display(double x) {
        System.out.println("double: " + x);
    }
}

public class Main {
    public static void main(String[] args) {
        Example obj = new Example();

        obj.display(10);     // int: 10
        obj.display(10.5);   // double: 10.5

        byte b = 5;
        obj.display(b);      // int: 5 (byte promoted to int)
    }
}

Promotion Order: byte → short → int → long → float → double


Ambiguous Overloading

class Ambiguous {
    void display(int a, double b) {
        System.out.println("int, double");
    }

    void display(double a, int b) {
        System.out.println("double, int");
    }
}

public class Main {
    public static void main(String[] args) {
        Ambiguous obj = new Ambiguous();

        obj.display(10, 20.5);   // ✓ OK: int, double
        obj.display(10.5, 20);   // ✓ OK: double, int
        // obj.display(10, 20);  // ❌ Error: Ambiguous
    }
}

Benefits of Overloading

  1. Readability: Same operation, same name
  2. Flexibility: Work with different types
  3. Convenience: Natural to use
  4. Code Reuse: Similar functionality

Real-World Example

class Area {
    // Area of square
    double calculate(double side) {
        return side * side;
    }

    // Area of rectangle
    double calculate(double length, double width) {
        return length * width;
    }

    // Area of circle
    double calculate(double radius, boolean isCircle) {
        if (isCircle) {
            return 3.14159 * radius * radius;
        }
        return 0;
    }
}

public class Main {
    public static void main(String[] args) {
        Area area = new Area();

        System.out.println("Square: " + area.calculate(5));
        System.out.println("Rectangle: " + area.calculate(4, 6));
        System.out.println("Circle: " + area.calculate(3, true));
    }
}

Overloading vs Overriding

OverloadingOverriding
Same classParent-child classes
Different parametersSame signature
Compile-timeRuntime
Static bindingDynamic binding
Can change return typeSame return type

Quick Reference

class Example {
    // Overloaded methods
    void method(int x) { }
    void method(double x) { }
    void method(int x, int y) { }
    void method(String x) { }
}

// Usage
Example obj = new Example();
obj.method(10);           // int version
obj.method(10.5);         // double version
obj.method(5, 10);        // two int version
obj.method("Hello");      // String version

Exam Tips

Remember:

  1. Same name, different parameters
  2. Different: number, type, or order of parameters
  3. Return type alone cannot differentiate
  4. In same class
  5. Decided at compile-time
  6. Applies to methods and constructors
  7. Type promotion happens automatically
  8. Provides flexibility
  9. Improves readability
  10. Example: System.out.println() is overloaded

Common Questions:

  • What is method overloading?
  • Rules for overloading?
  • Can return type differentiate?
  • Overloading vs Overriding?
  • What is type promotion?
  • Benefits of overloading?
  • Can constructors be overloaded?