Menu

Method Overloading and Method Overriding

Method Overloading and Method Overriding

Chapter 6 introduced overloading and overriding as the two faces of polymorphism. This chapter goes deeper: the exact rules Java enforces for each, where they are used in practice, and the small but important differences beginners often mix up between them.

What is Method Overloading?

Method overloading happens when a class contains two or more methods that share the same name but accept a different set of parameters. It lets a single, memorable method name handle several related variations of the same basic operation.

class Printer {

void print(String text) {

System.out.println(text);

}

void print(String text, int copies) {

for (int i = 0; i < copies; i++) {

System.out.println(text);

}

}

}

Callers can use print("Hello") for a single copy, or print("Hello", 3) for three, without needing to remember two completely different method names for what is conceptually the same action.

Rules of Method Overloading

• The method name must stay exactly the same across all overloaded versions.

• The parameter list must differ, either in the number of parameters, their data types, or their order.

• The return type alone is not enough to distinguish two overloads; two methods with identical parameter lists but different return types will not compile.

• Overloaded methods can have different access modifiers and can optionally throw different exceptions, neither affects whether overloading is valid.

• Overloading can happen within the same class, or between a superclass and subclass (a subclass can add a new overload alongside an inherited one).

class Demo {

void show(int x) { }

// void show(int y) { }  // INVALID — identical parameter list, won't compile

void show(int x, int y) { }   // VALID — different number of parameters

void show(double x) { }    // VALID — different parameter type

}

What is Method Overriding?

Method overriding happens when a subclass provides its own implementation of a method that is already defined in its superclass, using the exact same method name and exact same parameter list. Unlike overloading, overriding always involves two classes connected by inheritance.

class Employee {

double calculateBonus() {

return 1000;

}

}

class Manager extends Employee {

@Override

double calculateBonus() {

return 5000;

}

}

A Manager object calling calculateBonus() will always return 5000, never falling back to the Employee version, because the subclass's implementation takes priority at runtime.

Rules of Method Overriding

• The method name and the parameter list must match the superclass version exactly.

• The return type must be the same, or a covariant type, a subtype of the original return type.

• The access modifier in the subclass cannot be more restrictive than in the superclass; you can widen visibility (protected to public) but never narrow it (public to private).

• A method marked final, static, or private in the superclass cannot be overridden; static methods can only be hidden, not truly overridden, and final methods are locked against any redefinition.

• The overriding method cannot throw a broader checked exception than the one declared in the superclass version.

class Vehicle {

protected String start() {

return "Vehicle starting";

}

}

class Car extends Vehicle {

@Override

public String start() {    // widening protected -> public is fine

return "Car engine starting";

}

}

Overloading vs Overriding

Aspect

Method Overloading

Method Overriding

Classes involved

Usually one class (can also span superclass/subclass)

Always two classes, linked by inheritance

Parameter list

Must differ

Must be identical

Return type

Can differ freely

Must match, or be a covariant subtype

Resolved by

Compiler, at compile time

JVM, at runtime

Polymorphism type

Compile-time (static)

Runtime (dynamic)

Purpose

Offer multiple ways to call a similarly-named operation

Let a subclass customise inherited behaviour

Use Cases and Examples

Overloading shows up constantly in everyday Java code, even code you have not written yourself. The println() method you have used throughout this tutorial is itself overloaded many times over, to accept a String, an int, a double, a boolean, and more, all under one familiar name.

System.out.println("Hello");   // calls println(String)

System.out.println(42);       // calls println(int)

System.out.println(3.14);     // calls println(double)

System.out.println(true);     // calls println(boolean)

Overriding shows up wherever a framework or library expects you to customise default behaviour. Almost every Java class implicitly inherits toString() from Object, and overriding it is one of the most common pieces of overriding you will write in real projects, so that printing an object shows something meaningful instead of a generic memory reference.

class Book {

String title;

Book(String t) {

title = t;

}

@Override

public String toString() {

return "Book: " + title;

}

}

Book b = new Book("Java Basics");

System.out.println(b);   // Book: Java Basics — instead of a memory address

Quick Tip

If you are ever unsure whether two methods overload or override each other, ask one question: are they in the same class with different parameters (overloading), or in a parent-child pair with the identical signature (overriding)? That single distinction resolves almost every confusion beginners run into here.