Difference between method overloading and method overriding in Java

This is quite often asked question with beginners in interviews. The tutorial lists out the differences in detail with examples. But before you start this tutorial refer method overloading and method overriding first if you don't know what they are. Let's see the differences one by one.

By Definition : When a class defines two or more than two methods with same name but different in parameters, we call it method overloading while when a subclass defines a method with same name and same in parameters(number and type of parameters) as in parent class, we call it method overriding.

 // Example of method overloading, add method is overloaded
 class A {
    int add(int a, int b) { ... }
    int add(int a, int b, int c) { ... }
    double add(double a, int b) { ... }
 }
 
 // Example of method overriding, add method is overridden
 class A {
    int add(int a, int b) { ... }
 }
 class B extends A {
    int add(int c, int d) { ... }
 }   

Class : Method overloading generally happens in same class while method overriding happens in two classes related using inheritance. In method overriding the subclass overrides the method of super class.

Parameter : In method overloading, each method must be different with other overloaded method either in number of parameters or type of parameters while in method overriding both(parent and child class) method must have same number or type of parameters. In other words, in method overloading method signature of each overloaded method must be different than other while in overriding the signature of both methods must be same.

Return type : Return type of a method doesn't play any role in method overloading but in method overriding, if the return type of parent class method is a primitive type, then the overriding method must also have same return type. If the return type of parent class method is non-primitive type then child class can use same non-primitive type or covariant return type(from java 1.5 onwards) as well to override the method.

What is covariant return type ?

If parent class method returns a non primitive type, then the overriding method in child class can return the same non primitive type or any of the subclasses of that non primitive type. All those subtypes would be called as covariant return type.

 class A {
    int add(int a, int b) { ... }    
    A getObj() { ... }
 }
 class B extends A {
    long add(int a, int b) { ... } // compilation error, return type must be int
    A getObj() { ... } // Valid override
    // OR
    B getObj() { ... } // Valid override, covariant return type
 }   

Access modifier : Access modifier also doesn't plays any role in method overloading but in method overriding, the subclass method should have either same access modifier or a more accessible modifier than parent class method. The child class method should not be more restrictive, doing so will result in compilation error.

 class A {
   void print(String s) { ... }    
 }
 class B extends A {
   private void print(String s) { .. } // compilation error, can't use more restrictive modifier
   // OR
   protected void print(String s) { ... } // valid override
   // OR
   public void print(String s) { ... } // valid override
 }   

Private, final and static method : The private, final and static methods in a class can be overloaded in java but they can not be overridden. Subclasses can not override such methods of parent class.

 class A {
    private int add(int a, int b) { ... } 
    int print(int a, int b, int c) { ... } // valid overload
    final void print(String s) { ... } 
    void print(String s, String t) { ... } // valid overload
 } 

throws clause : In method overloading, each overloaded method can throw any exception. In case of method overriding, if parent class method doesn't throws any exception child class method can not throw any checked exception. If parent class method throws any unchecked or runtime exception then the child class method can throw only unchecked or runtime exception or overriding method can ignore to declare any exception.

If parent class method throws any checked or compile time exception then the child class method can throw the same exception or a subclass of that exception. It can not throw a superclass of parent class method exception. The subclass method can throw any unchecked or runtime exception.

 class A {
   void print() { } 
   void message() throws NullPointerException { } // Unchecked Exception
   void run() throws IOException { } // Checked Exception
 }
 class B extends A {
   void print() throws IOException { } // compilation error, can't throw checked exception
   void message() throws IOException { } // compilation error, can't throw checked exception
   void message() throws NullPointerException { } // valid override
   void run() throws Exception { } // compilation error, Exception is not subclass of IOException
   void run() throws IOException { } // valid override
 }   

Method Resolution : Method resolution is a technique in which the compiler/jvm decides which particular form of an overloaded/overridden method will be called when the program will run. In method overloading, this resolution happens at compile time by the compiler itself while in method overriding the resolution happens at runtime by JVM.

Polymorphism : Method overloading is an example of compile time polymorphism or static binding or early binding while method overriding is an example of runtime polymorphism or dynamic binding or late binding.

Method overloading vs method overriding in tabular format

Method Overloading Method Overriding
By Definition If a class defines two or more than two methods with same name but different in parameters, we call it method overloading. If a subclass defines a method with same signature as in parent class, we call it method overriding.
Class Generally happens in same class. One method should be in parent class while other should be in child class.
Parameter Each overloaded method must be different in number or type of parameters from other. Both method must have same number and type of parameters in same order.
Return Type Return type of a method doesn't play any role in method overloading. Must be the same if it is primitive type, if it's a non-primitive type then a covariant return type can be used from java 1.5 onwards.
Access modifier Access modifier of a method doesn't plays any role in method overloading. Subclass method must have same or more accessible modifier than the parent class method.
private, final and static method Such methods can also be overloaded. Such methods can not be overridden.
throws clause Each overloaded method can declare to throw any exception. If parent class doesn't throws any exception, then child class can not throw any checked exception. Refer throws clause section given above for more details.
Method Resolution It's the compiler that resolves method call at compile time itself. It's jvm that resolves the method call at runtime.
Polymorphism It is an example of compile time polymorphism. It is an example of run time polymorphism.