Method Overriding in Java
Method overriding is a process of overriding base class method by derived class method with more specific definition.
Method overriding performs only if two classes have is-a relationship. It mean class must have inheritance. In other words, It is performed between two classes using inheritance relation.
In overriding, method of both class must have same name and equal number of parameters.
Method overriding is also referred to as runtime polymorphism because calling method is decided by JVM during runtime.
The key benefit of overriding is the ability to define method that's specific to a particular subclass type.
Rules for Method Overriding
1. Method name must be same for both parent and child classes.
2. Access modifier of child method must not restrictive than parent class method.
3. Private, final and static methods cannot be overridden.
4. There must be an IS-A relationship between classes (inheritance).
Example of Method Overriding
Below we have simple code example with one parent class and one child class wherein the child class will override the method provided by the parent class.
class Animal
{
public void eat()
{
System.out.println("Eat all eatables");
}
}
class Dog extends Animal
{
public void eat() //eat() method overridden by Dog class.
{
System.out.println("Dog like to eat meat");
}
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
}
}
Dog like to eat meat
As you can see here Dog class gives it own implementation of eat()
method. For method overriding, the method must have same name and same type signature in both parent and child class.
NOTE: Static methods cannot be overridden because, a static method is bounded with class where as instance method is bounded with object.
Example: Access modifier is more restrictive in child class
Java does not allows method overriding if child class has more restricted access modifier than parent class.
In the below example, to the child class method, we set protected which is restricted than pubic specified in parent class.
class Animal
{
public void eat()
{
System.out.println("Eat all eatables");
}
}
class Dog extends Animal
{
protected void eat() //error
{
System.out.println("Dog like to eat meat");
}
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
}
}
Cannot reduce the visibility of the inherited method from Animal.
Covariant return type
Since Java 5, it is possible to override a method by changing its return type. If subclass override any method by changing the return type of super class method, then the return type of overriden method must be subtype of return type declared in original method inside the super class. This is the only way by which method can be overriden by changing its return type.
Example :
class Animal
{
Animal getObj()
{
System.out.println("Animal object");
return new Animal();
}
}
class Dog extends Animal
{
Dog getObj() //Legal override after Java5 onward
{ System.out.println("Dog object");
return new Dog();
}
public static void main(String[] args) {
new Dog().getObj();
}
}
Dog object
Difference between Overloading and Overriding
Method overloading and Method overriding seems to be similar concepts but they are not. Let's see some differences between both of them:
Method Overloading |
Method Overriding |
Parameter must be different and name must be same. |
Both name and parameter must be same. |
Compile time polymorphism. |
Runtime polymorphism. |
Increase readability of code. |
Increase reusability of code. |
Access specifier can be changed. |
Access specifier cannot be more restrictive than original method(can be less restrictive). |
It is Compiled Time Polymorphism. |
It is Run Time Polymorphism. |
It is performed within a class |
It is performed between two classes using inheritance relation. |
It is performed between two classes using inheritance relation. |
It requires always inheritance. |
It should have methods with the same name but a different signature. |
It should have methods with same name and signature. |
It can not have the same return type. |
It should always have the same return type. |
It can be performed using the static method |
It can not be performed using the static method |
It uses static binding |
It uses the dynamic binding. |
Access modifiers and Non-access modifiers can be changed. |
Access modifiers and Non-access modifiers can not be changed. |
It is code refinement technique. |
It is a code replacement technique. |
No keywords are used while defining the method. |
Virtual keyword is used in the base class and overrides keyword is used in the derived class. |
Private, static, final methods can be overloaded |
Private, static, final methods can not be overloaded |
No restriction is Throws Clause. |
Restriction in only checked exception. |
It is also known as Compile time polymorphism or static polymorphism or early binding |
It is also known as Run time polymorphism or Dynamic polymorphism or Late binding |
Example
class OverloadingDemo{
static int add1(int x,int y){return x+y;}
static int add1(int x,int y,int z){return x+y+z;}
}
|
Example:
class Demo2{
void a()
{System.out.println("A");}}
class b extends c
{void a(){System.out.println("B");}
|
Q. Can we Override static method? Explain with reasons?
No, we cannot override static method. Because static method is bound to class whereas method overriding is associated with object i.e at runtime.
Example: Overriding toString()
The toString() method of Object class is used to return string representation of an object.
Since object is super class of all java classes then we can override its string method to provide our own string presentation.
If we don’t override string class and print object reference then it prints some hash code in "class_name @ hash code"
format.
Below is an example of the overriding toString()
method of Object class.
class Demo{
private double a, b;
public Demo(double a, double b)
{
this.a = a;
this.b = b;
}
@Override
public String toString()
{
return String.format(a + " + i" + b);
}
}
public class MethodDemo11{
public static void main(String[] args)
{
Demo obj1 = new Demo(25, 10);
System.out.println(obj1);
}
}