Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
Method overriding in Java is a core concept of object-oriented programming that allows a subclass to provide a specific implementation of a method already defined in its superclass.
What is method overriding in Java?
Method overriding in Java is a feature that allows a subclass to provide a specific implementation of a method that is already defined in its superclass. It is a key aspect of polymorphism, enabling dynamic method dispatch. When a method is overridden, the subclass method is called at runtime, allowing for specific behavior in the subclass while maintaining the same method signature as the superclass. This enhances code flexibility and reusability. In method overriding in Java, the parent class method is called the overridden method, and the child class method is called the overriding method.
How does Method Overriding in Java Work?
The parent class(or base class) methods are by default available in the child class(or derived class) through inheritance. However, if the child class requires any specific implementation for the method declared in the parent class.
It can redefine the method based on its requirements. The method to be invoked is decided at runtime by the Java Virtual Machine (JVM) based on the runtime object (not on the reference type).
If a parent class object is used to invoke the method, then the parent class method is executed, but if a child class object is used to invoke the method, then the child class method is executed.
Here are some ways Java Method Overriding can be used:
Extending functionality: Subclasses can override methods from their superclass to add or modify functionality.
Polymorphism: Allows objects of different subclasses to be treated as objects of their superclass, enabling more flexible and modular code.
Adhering to contracts: Overridden methods should have the same name, parameters, and return type as the superclass method to ensure adherence to contracts.
Specialization: Subclasses can override methods to provide specialized implementations based on their unique requirements.
Implementing abstract methods: Subclasses of an abstract class must override its abstract methods to provide concrete implementations.
Let’s look at the example to understand Method Overriding in Java. Before that, let’s understand the problem that occurs if method overriding is not used.
Implementation in Java without using method overriding
Java
Java
class Human { public void job() { System.out.println("Working Professional"); } }
class Teacher extends Human { }
class Doctor extends Human { }
public class Main { public static void main(String[] args) { Human h1 = new Human(); Teacher t1 = new Teacher(); Doctor d1 = new Doctor(); Human h2 = new Doctor(); // method invoked based on human object h1.job(); // method invoked based on teacher object t1.job(); // method invoked based on doctor object d1.job(); // method invoked based on doctor object h2.job(); } }
You can also try this code with Online Java Compiler
Working Professional
Working Professional
Working Professional
In the above example, the base class is Human, and the child classes are Teacher and Doctor. When the job() method is called, the parent method is called in every case. In this case, it is not possible to provide a specific implementation of the job() method in the child class. To solve this issue, method overriding is used.
Implementation in Java using method overriding
Java
Java
class Human { // overridden method public void job() { System.out.println("Working Professional"); } }
class Teacher extends Human { // overriding method public void job() { System.out.println("Teacher"); } }
class Doctor extends Human { // overriding method public void job() { System.out.println("Doctor"); } }
public class Main { public static void main(String[] args) { Human h1 = new Human(); Teacher t1 = new Teacher(); Doctor d1 = new Doctor(); Human h2 = new Doctor(); // method invoked based on human object h1.job(); // method invoked based on teacher object t1.job(); // method invoked based on doctor object d1.job(); // method invoked based on doctor object h2.job(); } }
You can also try this code with Online Java Compiler
In the above case, the job() method in the child class has a specific implementation. When the job() method is called, the appropriate method will be called depending on the runtime object.
1. The methods should have the same method signature, and there must be inheritance involved. Until Java5, the same return type was also required for overriding.
In the earlier versions of Java, it was not possible to override any method by changing the return type. In Java5, a concept called covariant return type was introduced, which allowed method overriding in Java by changing the return type.
Covariant return type allows to narrow down the return type of an overridden method without casting the type or checking the return type. It works only for non-primitive return types.
Some of the possible cases:
Return Type of Parent Class Method
Possible Return Types for Child Class Method
Object
Object, String, String, StringBuffer, etc
Number
Number, Integer, Float, Long, etc
String
String
Example
Java
Java
class Obj { // return type object public Object f1() { return "I am a Object."; } }
class Str extends Obj { // return type String public String f1() { return "I am a String."; } }
class Main { public static void main(String[] args) { Str strObj = new Str(); System.out.println(strObj.f1()); } }
You can also try this code with Online Java Compiler
A method is made final when specific implementations are not required. When a method is declared final, the child class cannot override it.
Example
class A {
// overriden final method
public final void f1() {
System.out.println("Class A method");
}
}
class B extends A {
// overriding non-final method
public void f1() {
System.out.println("Class B method");
}
}
class Main {
public static void main(String[] args) {
A a = new A();
a.f1();
};
}
Output
This can be resolved by making the overridden method non-final. However, it is possible to make the overriding method final.
Java
Java
class A { // overriden non-final method public void f1() { System.out.println("Class A method"); } }
class B extends A { // overriding final method public final void f1() { System.out.println("Class B method"); } }
class Main { public static void main(String[] args) { A a = new A(); B b = new B(); a.f1(); b.f1(); }; }
You can also try this code with Online Java Compiler
3. Reducing the scope of access modifiers in the overriding method rather than the overridden method is not possible.
The child class is an instance of the parent class and should have at least the same level of access. For example, a protected overridden method can only have a public or protected overriding method.
Accessibility Scope:
Private < Default < Protected < Public
Access Modifier of Parent Class Method
Possible Access Modifiers for Child Class Method
Public
Public
Protected
Protected, Public
Default
Default, Protected, Public
Example
Java
Java
class A { // overriden method with public access modifier public void f1() { System.out.println("Class A method"); } }
class B extends A { // overriding method with default access modifier default void f1() { System.out.println("Class B method"); } }
class Main { public static void main(String[] args) { A a = new A(); B b = new B(); a.f1(); b.f1(); }; }
You can also try this code with Online Java Compiler
This can be resolved by making the overriding method public.
Note: A private method cannot be overridden. Private methods are not visible to any other class, limiting their scope to the child class. They get bonded during the compile-time, so it’s not possible to override private methods in a subclass.
Example
class A {
// overriden method with public access modifier
private void f1() {
System.out.println("Class A method");
}
}
class B extends A {
// overriding method with default access modifier
void f1() {
System.out.println("Class B method");
}
}
class Main {
public static void main(String[] args) {
A a = new B();
a.f1();
}
}
Output
4. If the child class throws a checked exception, the parent class should throw the same exception or parent exception. Else a compile-time error would occur.
For example, if a child class throws ArithmeticException, the parent class can only throw the parent exceptions of ArithmeticException, RunTimeException, or Exception and not any other exceptions like IOException. This is because the compiler cannot catch the exception in this case.
Since unchecked exceptions can be thrown anywhere, this rule is not applicable to them.
Example
import java.io.IOException;
class A {
// overriden method with IOException
public void f1() throws IOException {
throw new IOException();
}
}
class B extends A {
// overriding method with Exception
public void f1() throws Exception {
try {
System.out.println("Class B method");
} catch(Exception e) {
System.out.println(e);
}
}
}
class Main {
public static void main(String[] args) {
B b = new B();
try {
b.f1();
} catch(Exception e) {
System.out.println(e);
}
}
}
Output
Compile-time error is caused in the above case because child class A throws a checked exception(Exception), but the parent class is throwing a child exception(IOException) instead of a parent exception.
The overriding method can only throw those checked exceptions, which have less scope than the exception declared in the overridden method.
Example
Java
Java
import java.io.IOException;
class A { // overriden method with IOException public void f1() throws Exception { try { System.out.println("Class B method"); } catch(Exception e) { System.out.println(e); } } } class B extends A { // overriding method with Exception public void f1() throws IOException { throw new IOException(); } } class Main { public static void main(String[] args) { B b = new B(); try { b.f1(); } catch(Exception e) { System.out.println(e); } } }
You can also try this code with Online Java Compiler
When child class and parent class are static with the same signature, it is called method hiding. The method in the parent class will be hidden by the one that is in the child class. In method hiding, method resolution is taken care of by the compiler based on the reference type.
In method overriding, the method to be invoked is decided at runtime. Static methods are bonded at compile-time, so static methods cannot be overridden in Java but static keywords do.
Example
Java
Java
class A { // overriden static method static void f1() { System.out.println("Class A method"); } } class B extends A { // overriding static method static void f1() { System.out.println("Class B method"); } } class Main { public static void main(String[] args) { A a = new A(); B b = new B(); a.f1(); b.f1(); } }
You can also try this code with Online Java Compiler
This does not generate any error. However, this is not method overriding.
6. A constructor cannot be overridden as a parent class, and a child class cannot have the constructors with the same name. The constructor name should always be the same as the class name.
7. A non-abstract method in the child class must override the abstract method declared in the parent class, vice-versa is not possible.
An abstract class cannot be used to create objects, and the implementation has to be provided by the sub-class. So it should have a non-abstract class to achieve method overloading.
Example
Java
Java
abstract class A { // overriden abstract method abstract void f1(); } class B extends A { // overriding non-abstract method void f1() { System.out.println("Class B method"); } } class Main { public static void main(String[] args) { B b = new B(); b.f1(); } }
You can also try this code with Online Java Compiler
8. A synchronised/strictfp/native method can correspondingly override a non-synchronised/non-strictfp/non-native method and vice-versa.
9. A child class in a different package can only override the non-final methods declared public or protected.
10. A child class within the same package as the instance’s parent class can override any parent class method that is not declared final or private.
super() in Method Overriding in Java
super() can be used to invoke a parent class overridden method in the child class method.
Example of super()
Java
Java
class A { // overridden method public void f1() { System.out.println("Overridden method"); } } class B extends A { // overriding method public void f1() { // overridden parent method called super.f1(); System.out.println("Overriding method"); } } class Main { public static void main(String[] args) { B b = new B(); b.f1(); } }
You can also try this code with Online Java Compiler
In the above example, both the overridden and overriding methods are executed with the help of super().
Real-world example of Method Overloading in Java
Consider a scenario where a school is taking admissions for the 11th standard, and a method has to be written to display the fee. The fee would vary according to the stream selected by the student, so method overriding can be used to get the fee of each stream.
Implementation in Java
Java
Java
class XIAddmission { // overriden method public int getFee() { int baseFee = 10000; return baseFee; } } class Science extends XIAddmission { // overriding method public int getFee() { int extraFee = 5000; return super.getFee() + extraFee; } }
class Commerce extends XIAddmission { // overriding method public int getFee() { int extraFee = 2500; return super.getFee() + extraFee; } }
class Humanities extends XIAddmission { // overriding method public int getFee() { int extraFee = 2000; return super.getFee() + extraFee; } } class Main { public static void main(String[] args) { Science s1 = new Science(); Commerce s2 = new Commerce(); Humanities s3 = new Humanities(); System.out.println("Fee for Science stream: Rs."+ s1.getFee()); System.out.println("Fee for Commerce stream: Rs."+ s2.getFee()); System.out.println("Fee for Humanities stream: Rs."+ s3.getFee()); } }
You can also try this code with Online Java Compiler
Fee For Science stream: Rs.15000
Fee For Commerce stream: Rs.12500
Fee For Humanities stream: Rs.12000
In the above example, XIAddmission class has a method getFee() to return the base fee. Each stream class has an overriding getFee() method, which includes the extra fee in the final fee.
Method overriding is also referred to as runtime polymorphism. It enables a subclass to provide a specific implementation of a method that is already defined in its superclass, allowing for dynamic method resolution during runtime based on the actual object type.
How can we prevent method overriding?
To prevent method overriding in Java, you can declare a method as final in the superclass. Final methods cannot be overridden by subclasses. Alternatively, declaring the entire class as final prevents any subclassing, hence preventing method overriding.
What is difference between method overloading and method overriding in Java?
Method overloading allows multiple methods with the same name but different parameters in the same class while the Method overriding allows a subclass to provide a specific implementation for a method which is already defined in its superclass.
Which methods can be overridden in Java?
Methods that can be overridden in Java are the Instance methods that are not declared final, static, or private can be overridden in Java.
Conclusion
Method overriding in Java allows a subclass to provide a specific implementation of a method already defined in its superclass. This feature promotes polymorphism, enabling dynamic method dispatch, and enhances code flexibility and maintainability by allowing different behaviors for inherited methods based on the object instance at runtime.