Method Overriding & Overloading

Method Overriding

Method overriding happens if the sub-class method satisfies the below conditions with the Super-class method:

  • Method name should be the same

  • The argument or parameters should be the same

  • Return type should also be the same

  • The method cannot have a weaker access modifier (e.g., protected method in superclass cannot be private in subclass).

  • The method cannot throw new or broader checked exceptions.

  • Only instance methods can be overridden (static methods are hidden, not overridden).

  • Subclass can return a subtype of the superclass method’s return type.

The key benefit of overriding is that the Sub-class can provide some specific information about that sub-class type than the super-class.

Example

// Basic Overriding Example
class Parent {
    void show() { System.out.println("Parent method"); }
}

class Child extends Parent {
    @Override
    void show() { System.out.println("Child method"); }
}

// Overriding with Covariant Return Type
// The overridden method in the subclass can return a subtype of the superclass method’s return type.
class Parent {
    Number getValue() { return 10; }
}

class Child extends Parent {
    @Override
    Integer getValue() { return 20; } // Covariant return type (Integer is a subtype of Number)
}

// Overriding with Exception Handling
// The overridden method cannot throw broader checked exceptions.
class Parent {
    void method() throws IOException {}  
}

class Child extends Parent {
    @Override
    void method() throws FileNotFoundException {} // Allowed (Narrower exception)
    
    // void method() throws Exception {} // Not allowed (Broader exception)
}

// Hiding Static Methods (Not Overriding)
// Static methods are not overridden, they are hidden.
class Parent {
    static void show() { System.out.println("Parent static method"); }
}

class Child extends Parent {
    static void show() { System.out.println("Child static method"); }
}

// Final Methods Cannot Be Overridden
class Parent {
    final void show() { System.out.println("Final method"); }
}

class Child extends Parent {
    // void show() {} // Compilation error (Cannot override final method)
}

// Using super to Call Parent Method
class Parent {
    void show() { System.out.println("Parent method"); }
}

class Child extends Parent {
    @Override
    void show() {
        super.show(); // Calls the parent method
        System.out.println("Child method");
    }
}

// Incorrect use of @Override
class Parent {
    void method(int a) {}
}

class Child extends Parent {
    // @Override void method(double a) {} // Compilation error (Not the same signature)
}

// Private methods cannot be overridden (they are not inherited)
class Parent {
    private void secret() {} 
}

class Child extends Parent {
    void secret() {} // This is a new method, NOT an override
}

// Illegal Case (Incompatible Covariant Type)
class Parent {
    Number getValue() {
        return 10;
    }
}

class Child extends Parent {
    @Override
    String getValue() { // Compilation error: String is NOT a subclass of Number
        return "Error";
    }
}

Method Overloading

Method overloading happens for different classes or within the same class.

For method overloading, sub-class method should satisfy the below conditions with the Super-class method (or) methods in the same class itself:

  • Same method name

  • Different argument types and ordering

  • Return type alone cannot differentiate overloaded methods. Does not support covariant return type.

  • They can have different access modifiers and exceptions.

Example

Overloading by Only Return Type ?

In Java, method overloading means having multiple methods in the same class with the same name but different parameter lists (number or type of arguments).

But if two methods have the same name and the same parameter list, but only differ in return type, the compiler cannot distinguish between them at the point of calling.

Example Case

Why This Fails ?

When we call:

  • The compiler sees the method call getValue() with no arguments.

  • Both methods int getValue() and double getValue() look identical in terms of method signature (method name + parameter list).

  • Java does not consider return type as part of the signature.

  • So, the compiler cannot figure out which version we want to call.

This would cause ambiguity.

What If Return Type Was Considered?

If Java allowed overloading based only on return type, then a call like this:

would leave the compiler confused. Should it return an int or a double? Unless we explicitly assign it:

the compiler has no way to know which method we meant. This would make method resolution complicated and ambiguous.

Last updated