Skip to main content

Everything About Method Overloading Vs Method Overriding

In a previous article Everything About ClassNotFoundException Vs NoClassDefFoundError, I have explained ClassNotFoundException and NoClassDefFoundError in details and also discussed their differences and how to avoid them. If you have not read it, please go ahead and give it a look.

Similar to that here in this article, we will look into one more core concept of Java which is method overloading and overriding. As soon as we start learning Java we get introduced to them and their contracts which are pretty simple to understand but sometimes programmers get confused between them or they do not know either it is a correct overload/override because of the different rules.

Here we will discuss What is method overloading and overriding, What contract one must follow to correctly overload or override a method, What are the different rules of method overloading and overriding and what are the differences between them.

Method Overloading

Method overloading means providing two separate methods in a class with the same name but different arguments while method return type may or may not be different which allows us to reuse the same method name.

And this becomes very handy for the consumer of our class, he can pass different types of parameters to the same method (in his eyes but actually they are different) and get the response according to his input e.g. System.out.println() method accepts all types of objects primitive types and print them but in reality there several println present in the PrintStream class.

public class PrintStream {

// other methods

public void println() { /*code*/ }
public void println(boolean x) { /*code*/ }
public void println(char x) { /*code*/ }
public void println(int x) { /*code*/ }
public void println(long x) { /*code*/ }
public void println(float x) { /*code*/ }
public void println(double x) { /*code*/ }
public void println(char x[]) { /*code*/ }
public void println(String x) { /*code*/ }
public void println(Object x) { /*code*/ }

// other methods
}

While overloading has nothing to deal with polymorphism but Java programmers also refer method overloading as Compile Time Polymorphism because which method is going to get called will be decided at compile time only.

In the case of method overloading compiler decides which method is going to get called based on the reference on which it is getting called and the method name, return type, and argument list.

class Human {
public String speak() { return "Hello"; }

// Valid overload of speak
public String
speak(String language) {
if (language.equals("Hindi")) return "Namaste";
else return "Hello";
}

public long calculate(int a, long b) { return a + b; }

// However nobody should do it but Valid overload of calculate
// by just changing sequence of arguments
public long calculate(long b, int a) { return a + b; }
}

Method Overloading Rules

There are some rules which we need to follow to overload a method and some of them are mandatory while some are optional.

Two methods will be treated as Overloaded if both follows below mandatory rule.
  • Both must have same method name
  • Both must have different argument lists
And if both methods follow above mandatory rules then they may or may not
  • Have different return types
  • Have different access modifiers
  • Throw different checked or unchecked exceptions
Usually, method overloading happens inside a single class but a method can also be treated as overloaded in the subclass of that class because subclass inherits one version of the method from the parent class and then can have another overloaded version in its class definition.

Method Overriding

Method Overriding means defining a method in the child class which is already defined in the parent class with same method signature i.e same name, arguments and return type (after Java 5 you can also use a covariant type as return type).

Whenever we extend a super class in a child class, child class automatically gets all the methods defined in the super and we call them derived methods. But in some cases we do not want some derived methods to work in a manner which they are doing in the parent then we can override those methods in child class e.g. we always override equals, hashCode and toString from Object class, you can read more on Why can't we override clone() method from Object class.

In case of abstract methods either from a parent abstract class or interface we do not have any option we need implement or in other words override all the abstract methods.

Method overriding is also known as Runtime Polymorphism and Dynamic Method Dispatch because which method is going to get called is decided at runtime by JVM.

abstract class Mammal {
// Well might speak something
public String speak() { return "ohlllalalalalalaoaoaoa"; }
}

class Cat extends Mammal {
@Override
public String speak() { return "Meow"; }
}

class Human extends Mammal {
@Override
public String speak() { return "Hello"; }
}

Using @Override annotation on the overridden methods is not necessary but using it will tell you if you are not obeying overriding rules. 

Mammal mammal = new Cat();
System.out.println(mammal.speak()); // Will print Meow

At the line mammal.speak() compiler says the speak() method of reference type Mammal is getting called, so for compiler this call is Mammal.speak().

But at the execution time JVM knows clearly that mammal reference is holding the reference of object of Cat, so for JVM this call is Cat.speak(). You can read more on How Does JVM Handle Method Overloading and Overriding Internally.

Method Overriding Rules

Similar to method overloading we also have some mandatory and some optional rules which we need to follow to override a method.

With respect to the method it overrides, the overriding method must follow below mandatory rule.
  • It must have same method name
  • Must have same arguments.
  • Must have the same return type, from Java 5 the return type can also be a subclass (Subclass is a covariant type to its parent).
  • Must not have a more restrictive access modifier (if parent --> protected then child --> private is not allowed).
  • Must not throw new or broader checked exceptions.
And if both overriding methods follow above mandatory rules then it
  • May have a less restrictive access modifier (if parent --> protected then child --> public is allowed).
  • May throw fewer or narrower checked exceptions or any unchecked exception.
Apart from above rules there are also some facts
  • Only inherited methods can be overridden, Means methods can be overridden in child class only.
  • Constructors and private methods are not inherited so can not be overridden.
  • Abstract methods must be overridden by the first concrete (non-abstract) subclass.
  • final methods cannot be overridden.
  • A subclass can use super.overridden_method() to call the superclass version of an overridden method.

Difference Between Method Overloading and Method Overriding


difference-between-method-overloading-and-method-overriding

You can find complete code on this Github Repository and please feel free to provide your valuable feedback.

Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. good post Naresh, understood the basic difference between the two.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why an outer Java class can’t be static

In a previous blog , I talked about why we can not define an outer class using private or protected keywords. If you have not read it, please go ahead and give it a look. I this article I will talk what is the use of the static keyword, why an outer Java class can’t be static, why it is not allowed in Java to define a static outer class. In order to understand that first, we need to understand what is the static keyword used for, what purpose it solves and how does it works. What does static keyword do Every Java programmer knows that if we need to define some behavior (method) or state (field) which will be common to all objects we define it as static. Because static content (behavior or state) does not belong to any particular instance or object, it will common to all objects and all objects are free to change any static field and every change will be visible to every object. We do not need to create any object of the class to access a static field or method, we can directly refer a

Why Single Java Source File Can Not Have More Than One public class

According to Java standards and common practices we should declare every class in its own source file. And even if we declare multiple classes in the single source file (.java) still each class will have its own class file after compilation. But the fact is that we can declare more than one class in a single source file with below constraints, Each source file should contain only one public class and the name of that public class should be similar to the name of the source file. If you are declaring the main method in your source file then main should lie in that public class If there is no public class in the source file then main method can lie in any class and we can give any name to the source file. If you are not following 1st constraint then you will receive a compilation error saying “ The public type A must be defined in its own file ”.  While if you are not following the second constraint you will receive an error “ Error: Could not find or load main class User ” after exec

Creating objects through Reflection in Java with Example

In Java, we generally create objects using the new keyword or we use some DI framework e.g. Spring to create an object which internally use Java Reflection API to do so. In this Article, we are going to study the reflective ways to create objects. There are two methods present in Reflection API which we can use to create objects Class.newInstance() → Inside java.lang package Constructor.newInstance() → Inside java.lang.reflect package However there are total 5 ways create objects in Java, if you are not aware of them please go through this article 5 Different ways to create objects in Java with Example . Both Class.newInstance() and java.lang.reflect.Constructor.newInstance() are known as reflective methods because these two uses reflection API to create the object. Both are not static and we can call earlier one on a class level object while latter one needs constructor level object which we can get by using the class level object. Class.newInstance() The Class class is the mo