Skip to content
  • Method Overriding vs Overloading · Java

Method Overriding vs Overloading

LearnViaNotes @learnvianotes· 4 min read

Overloading = same name, different parameters, chosen at compile time. Overriding = same signature in a subclass, chosen at runtime.

Side by side

OverloadingOverriding
WhereSame class (or inherited)Subclass redefines a superclass/interface method
SignatureSame name, different parameter listSame name and same parameters
Return typeAnythingSame or a subtype (covariant)
AccessAnythingSame or wider
Checked exceptionsAnythingSame, narrower or none — never new/broader
ResolvedCompile time (static binding)Runtime (dynamic dispatch)
static / private / finalCan be overloadedCannot be overridden
Polymorphism kindCompile-timeRuntime

Overloading

Java
public class Main {
    static String show(int x)          { return "int " + x; }
    static String show(long x)         { return "long " + x; }
    static String show(double x)       { return "double " + x; }
    static String show(Integer x)      { return "Integer " + x; }
    static String show(Object x)       { return "Object " + x; }
    static String show(int... xs)      { return "varargs " + xs.length; }

    public static void main(String[] args) {
        byte b = 5;
        System.out.println(show(7));        // exact match
        System.out.println(show(b));        // widening byte → int beats boxing
        System.out.println(show(7L));
        System.out.println(show(7.0f));     // float → double
        System.out.println(show("hi"));     // String → Object
        System.out.println(show());         // only varargs fits
    }
}
Output
int 7
int 5
long 7
double 7.0
Object hi
varargs 0

Overriding with @Override

Java
public class Main {
    public static void main(String[] args) {
        Shape s = new Circle(2);           // reference type Shape, object Circle
        System.out.println(s.name());      // runtime: Circle.name()
        Circle copy = new Circle(2).copy();   // covariant return: no cast needed
        System.out.printf("%.2f%n", copy.area());
    }
}

class Shape {
    protected String name() { return "shape"; }
    Shape copy() { return new Shape(); }
    double area() { return 0; }
}

class Circle extends Shape {
    private final double r;
    Circle(double r) { this.r = r; }

    @Override public String name() { return "circle"; }        // protected → public: widening OK
    @Override Circle copy() { return new Circle(r); }          // covariant return type
    @Override double area() { return Math.PI * r * r; }
}
Output
circle
12.57
Java
class Point {
    int x;
    @Override
    public boolean equals(Point other) { return other.x == x; }   // wrong parameter type
}
javac
Main.java:3: error: method does not override or implement a method from a supertype
    @Override
    ^

Rules the compiler enforces

Java
import java.io.IOException;

class Parent {
    public void run() { }
    void load() throws IOException { }
}

class Child extends Parent {
    @Override protected void run() { }   // narrowing public → protected
}
javac
Main.java:9: error: run() in Child cannot override run() in Parent
    @Override protected void run() { }   // narrowing public → protected
                             ^
  attempting to assign weaker access privileges; was public
  • An override may throw fewer or narrower checked exceptions (FileNotFoundException instead of IOException), or none; unchecked exceptions are unrestricted.

  • final methods can't be overridden; private methods aren't inherited, so a same-named subclass method is just a new method.

  • Call the parent version with super.method().

Static methods are hidden, not overridden

Java
public class Main {
    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.stat());      // static: chosen by reference type
        System.out.println(p.inst());      // instance: chosen by object type
        System.out.println(p.label);       // fields are hidden too
        System.out.println(((Child) p).label);
    }
}

class Parent {
    String label = "parent-field";
    static String stat() { return "Parent.stat"; }
    String inst() { return "Parent.inst"; }
}

class Child extends Parent {
    String label = "child-field";
    static String stat() { return "Child.stat"; }
    @Override String inst() { return "Child.inst"; }
}
Output
Parent.stat
Child.inst
parent-field
child-field

Can we overload main?

Can we override a static or private method?

Can two overloads differ only by return type?

What is a covariant return type?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report