Java Method Overloading vs. Method Overriding

Java supports both, method overloading and method overriding (in other words, polymorphism), as two important concepts in object-oriented programming. They are used to achieve different goals and have distinct characteristics.

It is also a commonly asked Java interview question. Let us understand the differences between method overloading and overriding with easy-to-follow examples.

1. Method Overloading vs. Method Overriding

Let us start with a side-by-side comparison of method overloading and method overriding in Java:

AspectMethod OverloadingMethod Overriding
DefinitionDefine multiple methods in the same class with the same name but different parameters.Provide a specific implementation for a method already defined in a superclass in a subclass with the same method signature.
InheritanceNot related to inheritance; overloaded methods are defined in the same class and not inherited.Closely related to inheritance; overridden methods are defined in the superclass and can be inherited by subclasses.
Return TypeCan have the same or different return types.Must have the same return type or a subtype in the subclass.
Method SignatureMethods have the same name but different parameters (number, type, or order).Methods have the same name, parameters, and return type.
PolymorphismAchieves compile-time polymorphism; the correct method is selected at compile time based on the method signature.Achieves runtime polymorphism; the method to be executed is determined at runtime based on the actual object type.

Now, let us dive into each concept in more detail.

2. Method Overloading

Method overloading allows us to define multiple methods in the same class with the same name but with different parameters (number, type, or order of parameters). Overloaded methods can have the same or different return types.

Here are a few rules that we should keep in mind while overloading any method:

2.1. Method Arguments must be Different

The first and most important rule to overload a method is to change the method signature. The method signature comprises the number of method arguments, type of arguments and order of arguments if there are multiple arguments.

In the following example, the method sum() is defined two times. Both methods accept two arguments. The first method takes arguments of type Integer, and the second method takes arguments of type Float and Integer. Here the number of method arguments is the same, but their types are different.

public class Calculator {

  public Integer sum(Integer a, Integer b) {
    return a + b;
  }

  public Integer sum(Float a, Integer b) { 
    return a.intValue() + b;
  }
}

2.2. Method Return Types are Not Considered

The return type of the method is not part of the method signature, so only changing the return type of the method does not amount to method overloading.

In the following example, the methods accept similar arguments and their return types differ. It is an invalid code and gives a compiler error “‘sum(Integer, Integer)’ is already defined in ‘Calculator’“.

public class Calculator {

  public Integer sum(Integer a, Integer b) {
    return a + b;
  }

  public Double sum(Integer a, Integer b) { 
    return new Double(a + b);
  }
}
Invalid overloading

2.3. Thrown Exceptions are Not Considered

The exceptions thrown from methods are also not considered when overloading a method. So if the overloaded method throws the same exception, a different exception, or does not throw any exception, there is no effect at all on method overloading.

public class Calculator {

  public Integer sum(Integer a, Integer b) throws NullPointerException{
    return a + b;
  }

  public Integer sum(Integer a, Integer b) throws IllegalArgumentException{
    return a + b;
  }
}

3. Method Overriding

Method overriding happens when a child class overrides a method from the parent class. Method overriding allows a subclass to provide a specific implementation for a method that is already defined in its superclass. The method signature (name, return type, and parameters) must be the same in both the superclass and subclass.

Overriding is closely related to inheritance. The overridden methods are defined in the superclass and can be inherited and overridden only by the subclasses.

Always remember these rules when overriding a method in Java.

3.1. Method Arguments must be Exactly the Same

The method argument list in overridden and overriding methods must be exactly the same. If they don’t match, we have created a different method.

In the following example, the Parent and the Child classes have methods with the same name and exact same parameters list. It is a valid method overriding.

class Parent {

  public Integer sum(Integer a, Integer b) {
    return a + b;
  }
}

class Child extends Parent {

  public Integer sum(Integer a, Integer b) {
    return a + b;
  }
}

3.2. Method Return Type can be Subtype in Child Class

The return type of the overriding method can be the child class of the return type declared in the overridden method.

In the following example, the method return type in Parent is Number, and in the Child class, it is Integer. It is a valid return type and thus considered the valid method overriding.

class Parent {

  public Number sum(Integer a, Integer b) {
    return a + b;
  }
}

class Child extends Parent {

  public Integer sum(Integer a, Integer b) {
    return a + b;
  }
}

If we use the incompatible return type in the Child class, we will get the compiler error.

class Parent {

  public Number sum(Integer a, Integer b) {
    return a + b;
  }
}

class Child extends Parent {

  public String sum(Integer a, Integer b) {
    return a.toString() + b.toString();
  }
}
'sum(Integer, Integer)' in 'Child' clashes with 'sum(Integer, Integer)' in 'Parent'; attempting to use incompatible return type

3.3. Thrown Exception can be Subtype in Child Class

The overriding method can not throw a checked exception higher in the hierarchy than thrown by the overridden method.

For example, the overridden method in Parent class throws FileNotFoundException, the overriding method in Child class can throw FileNotFoundException; but it is not allowed to throw IOException or Exception, because IOException or Exception are higher in the hierarchy.

class Parent {
  public String readFile(String file) throws FileNotFoundException {
    //...
    return null;
  }
}

class Child extends Parent {
  public String readFile(String file) throws IOException {
    //...
    return null;
  }
}

In the above code, we will get the compiler error:

'readFile(String)' in 'Child' clashes with 'readFile(String)' in 'Parent'; overridden method does not throw 'java.io.IOException'

Note that we can omit the exception declaration from the overriding method. It’s allowed and perfectly valid. Also, the overriding method can throw any unchecked (runtime) exception, regardless of whether the overridden method declares that exception or not.

In the following example, the overriding method omits the FileNotFoundException and declares the RuntimeException which is an unchecked exception. This is a valid method overriding.

class Parent {
  public String readFile(String file) throws FileNotFoundException {
    //...
    return null;
  }
}

class Child extends Parent {
  public String readFile(String file) throws RuntimeException {
    //...
    return null;
  }
}

3.4. The private, static and final methods can not be Overridden

The private, static and final methods can not be overridden in Java in any way.

  • The private modifier restricts the method to class.
  • The static members belong to the class object.
  • The final keyword is used with members that must not be overridden.

In the following example, Parent and Child classes declare the method with the same name and parameters, But it is not method overriding. The readFile() is never accessible outside the Parent class.

class Parent {
  private String readFile(String file){
    //...
    return null;
  }
}

class Child extends Parent {
  public String readFile(String file) {
    //...
    return null;
  }
}

3.5. Overriding Method can not Reduce Access Scope

Also, note that the overriding method can not reduce the access scope of the overridden method.

For example, if the overridden method in Parent class is protected, then the overriding method in Child class can not be private. It must be either protected (same access) or public (wider access).

class Parent {
  protected String readFile(String file){
    //...
    return null;
  }
}

class Child extends Parent {
  public String readFile(String file) {
    //...
    return null;
  }
}

4. How to Verify if Method Overriding is Correct

To verify that we are correctly overriding a method or not, simply use the annotation @Override on the overriding method in the Child class. This will verify all the method-overriding rules. If there is any issue in overriding, it will result in a compile-time error.

class Parent {
  protected String readFile(String file){
    //...
    return null;
  }
}

class Child extends Parent {
  @Override
  public String readFile(String file) {
    //...
    return null;
  }
}

That’s all for this simple yet important concept to brush your basics in core Java and object-oriented programming.

5. Conclusion

We can conclude with the above discussion that method overloading provides multiple ways to call a method within the same class, while method overriding provides a specific implementation of a method in a subclass to customize its behavior while maintaining a common interface defined in the superclass.

Happy Learning !!

Comments

Subscribe
Notify of
guest
8 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode