Method Overloading vs Overriding

Naveen AnamaneniUpdated · 5 min read

Overloading and overriding sound alike and both reuse a method name, so they're easy to mix up. They are actually opposites in almost every way. Overloading is several methods with the same name and different parameters, chosen by the compiler. Overriding is one method replaced in a subclass with the same parameters, chosen by the JVM at runtime. This lesson puts them side by side, then shows a real bug caused by confusing them.

Side by Side

OverloadingOverriding
What it isSame name, different parameter listsSame name, same parameter list, in a subclass
WhereUsually in one class (or inherited into it)Parent and child classes
Decided byThe compiler, from declared argument typesThe JVM, from the object's actual class
PolymorphismCompile-time (static)Runtime (dynamic)
Return typeCan be anythingSame, or a subtype
Access modifierAnySame or wider
Checked exceptionsAnyNone, same or narrower
static methodsCan be overloadedCan't be overridden (they're hidden)
private and final methodsCan be overloadedCan't be overridden
AnnotationNone@Override

Both in One Program

Both.java▶ Try it
public class Both {
    static class Printer {
        void print(String s) { System.out.println("Printer: " + s); }
        void print(int n) { System.out.println("Printer number: " + n); }
    }
 
    static class ColorPrinter extends Printer {
        @Override
        void print(String s) { System.out.println("Color: " + s); }
    }
 
    public static void main(String[] args) {
        Printer p = new ColorPrinter();
        p.print("Navika");
        p.print(42);
    }
}
Output
Color: Navika
Printer number: 42

How it works

  1. print(String) and print(int) in Printer are overloads. For p.print(42), the compiler picks print(int) from the argument type.
  2. ColorPrinter overrides only print(String). For p.print("Navika"), the compiler picks print(String), then at runtime the JVM sees a ColorPrinter object and runs its version.
  3. print(int) isn't overridden, so the inherited Printer version runs.

So both mechanisms work together in two steps: the compiler chooses the signature, then the JVM chooses the implementation of that signature.

The equals Trap

This class tries to override equals but actually overloads it:

Trap.java▶ Try it
public class Trap {
    static class Account {
        String id;
        Account(String id) { this.id = id; }
 
        public boolean equals(Account other) {
            return id.equals(other.id);
        }
    }
 
    public static void main(String[] args) {
        Account a = new Account("A-101");
        Account b = new Account("A-101");
        Object o = b;
        System.out.println(a.equals(b));
        System.out.println(a.equals(o));
    }
}
Output
true
false

How it works

  1. Object declares equals(Object). The class declares equals(Account): a different parameter type, so it's an overload. Account now has two equals methods.
  2. a.equals(b): the argument's declared type is Account, so the compiler picks the new method, which compares ids: true.
  3. a.equals(o): the declared type is Object, so the compiler picks the inherited Object.equals, which compares references: false.
  4. Collections such as HashSet and ArrayList.contains always call equals(Object), so they'd never use your method.

Common Mistakes

Calling an overload "overriding" in an interview. The parameter list is the deciding question: different means overloading.

Expecting overloads to be chosen by the runtime object. They're chosen by declared types at compile time.

Overloading methods inherited from Object by accident. equals(Account) and compareTo with the wrong type are classic examples.

Interview Corner

What is the difference between method overloading and method overriding?

Overloading is defining methods with the same name but different parameter lists, usually in the same class; the compiler picks one from the declared argument types, so it's compile-time polymorphism, and return types, access and exceptions can differ freely. Overriding is redefining an inherited instance method with the same signature in a subclass; the JVM picks the version from the object's actual class at runtime, and the override must keep a compatible return type, equal or wider access, and no broader checked exceptions. Static, private and final methods can be overloaded but not overridden.

Can we overload and override the main method?

main can be overloaded: other methods named main with different parameters are allowed, but the JVM starts the program only from the standard main signature. A static main can't be overridden; a subclass's static main only hides it.

Practice

  1. Easy: In a Calculator class, overload add for two and three ints. In ScientificCalculator, override the two-argument version to print a log line before adding.
  2. Harder: Fix the Trap class so both lines print true, using @Override and a parameter of type Object.

Quick check: Overloading vs overriding

4 questions
1Who decides which overload runs?
2Who decides which overriding method runs?
3public boolean equals(Account other) in Account is:
4Which can be overloaded but not overridden?

Key Takeaways

Was this tutorial helpful?

Lesson 125 of 482