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.
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.
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.
Two methods will be treated as Overloaded if both follow below mandatory rule.
Whenever we extend a superclass 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
In case of abstract methods either from a parent abstract class or interface we do not have any option we need to implement or in other words override all the abstract methods.
At the line
But at the execution time JVM knows clearly that
With respect to the method it overrides, the overriding method must follow below mandatory rule.
You can find complete code on this Github Repository and please feel free to provide your valuable feedback.
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 follow below mandatory rule.
- Both must have same method name
- Both must have different argument lists
- Have different return types
- Have different access modifiers
- Throw different checked or unchecked exceptions
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 superclass 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 to 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.
- 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.
- Only inherited methods can be overridden, Means methods can be overridden in child class only.
- Constructors and private methods are not inherited so cannot 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
You can find complete code on this Github Repository and please feel free to provide your valuable feedback.