Unit 3 · OOP Concepts

3.1.6Overloading

Overloading means having several methods (or constructors) with the same name but different parameter lists in one class. The compiler chooses the correct one from the arguments. This is compile-time polymorphism.

The parameter lists must differ in number, type or order of parameters. Changing only the return type is not overloading.

callsmethods in Calculatorc.add(2, 3)int add(int a, int b)c.add(2, 3, 4)int add(int a, int b, int c)c.add(2.5, 1.5)double add(double a, double b)same name, different parameter lists: chosen at compile time
Overloading: the compiler picks the method whose parameter list matches the arguments
Java
class Calculator {
    int add(int a, int b)             { return a + b; }
    int add(int a, int b, int c)      { return a + b + c; }
    double add(double a, double b)    { return a + b; }
}

Calculator c = new Calculator();
c.add(2, 3);          // 5      (int, int)
c.add(2, 3, 4);       // 9      (three ints)
c.add(2.5, 1.5);      // 4.0    (double, double)

Constructor overloading has already been used in the Student class (see 3.1.4): it has three constructors with different parameter lists.

Some languages (C++, C#, Python) also allow operator overloading, where operators such as + are redefined for objects. Java does not allow it, except the built-in use of + to join strings.

Why overloading is useful

Without overloading you would need a different name for every version: addTwoInts, addThreeInts, addDoubles. With overloading, there is one easy-to-remember name for one idea, "add", and the compiler works out which version you mean. You already use overloading every day: System.out.println has separate versions for int, double, char, boolean, String and objects, which is why println(5) and println("Hi") both work.

How the compiler chooses

The compiler looks at the number, types and order of the arguments and picks the method whose parameter list matches best:

  1. First it looks for an exact match: c.add(2, 3) matches add(int, int).
  2. If there is none, it tries widening conversions, such as int to long or int to double. If only add(double, double) existed, c.add(2, 3) would still compile and return 5.0.
  3. If no method matches, or two methods match equally well, it is a compile error.

Because this choice is made when the code is compiled, not while it runs, overloading is called compile-time (static) polymorphism.

Valid and invalid overloads

MethodsValid?Why
print(int x) and print(String s)YesDifferent parameter types
area(double r) and area(double w, double h)YesDifferent number of parameters
show(int a, String b) and show(String b, int a)YesDifferent order of types
int total(int a) and double total(int a)NoOnly the return type differs
sum(int a, int b) and sum(int x, int y)NoOnly the parameter names differ

The last two rows fail because, when the code says total(5), the compiler has no way to tell which one you mean. Only the parameter types count, not their names.

Ambiguous calls: with the methods f(int a, double b) and f(double a, int b), the call f(1, 2) does not compile. Both methods need one widening conversion, so neither is a better match.

Remember

  • Overloaded methods share a name but differ in the number, type or order of their parameters.
  • The return type and parameter names do not count.
  • The compiler picks the version, so overloading is compile-time polymorphism.