Overriding and Exception-Handling
Below are two rules to note when overriding methods related to exception handling.
Rule #1
If the super-class overridden method does not throw an exception, the subclass overriding method can only throw the unchecked exception, throwing a checked exception will lead to a compile-time error.
Java
// Java program to demonstrate overriding when // superclass method does not declare an exception class Parent { void m1() { System.out.println( "From parent m1()" ); } void m2() { System.out.println( "From parent m2()" ); } } class Child extends Parent { @Override // no issue while throwing unchecked exception void m1() throws ArithmeticException { System.out.println( "From child m1()" ); } @Override // compile-time error // issue while throwing checked exception void m2() throws Exception { System.out.println( "From child m2" ); } } |
Output
error: m2() in Child cannot override m2() in Parent
void m2() throws Exception{ System.out.println("From child m2");}
^
overridden method does not throw Exception
Rule #2
If the superclass overridden method does throw an exception, the subclass overriding method can only throw the same, subclass exception. Throwing parent exceptions in the Exception hierarchy will lead to compile time error. Also, there is no issue if the subclass overridden method is not throwing any exception.
Java
// Java program to demonstrate overriding when // superclass method does declare an exception class Parent { void m1() throws RuntimeException { System.out.println( "From parent m1()" ); } } class Child1 extends Parent { @Override // no issue while throwing same exception void m1() throws RuntimeException { System.out.println( "From child1 m1()" ); } } class Child2 extends Parent { @Override // no issue while throwing subclass exception void m1() throws ArithmeticException { System.out.println( "From child2 m1()" ); } } class Child3 extends Parent { @Override // no issue while not throwing any exception void m1() { System.out.println( "From child3 m1()" ); } } class Child4 extends Parent { @Override // compile-time error // issue while throwing parent exception void m1() throws Exception { System.out.println( "From child4 m1()" ); } } |
Output
error: m1() in Child4 cannot override m1() in Parent
void m1() throws Exception
^
overridden method does not throw Exception
Overriding and Abstract Method
Abstract methods in an interface or abstract class are meant to be overridden in derived concrete classes otherwise a compile-time error will be thrown.
Overriding and Synchronized/strictfp Method
The presence of a synchronized/strictfp modifier with the method has no effect on the rules of overriding, i.e. it’s possible that a synchronized/strictfp method can override a non-synchronized/strictfp one and vice-versa.
Note:
- In C++, we need virtual keyword to achieve overriding or Run Time Polymorphism. In Java, methods are virtual by default.
- We can have multilevel method-overriding.
Java
// A Java program to demonstrate // multi-level overriding // Base Class class Parent { void show() { System.out.println( "Parent's show()" ); } } // Inherited class class Child extends Parent { // This method overrides show() of Parent void show() { System.out.println( "Child's show()" ); } } // Inherited class class GrandChild extends Child { // This method overrides show() of Parent void show() { System.out.println( "GrandChild's show()" ); } } // Driver class class Main { public static void main(String[] args) { Parent obj1 = new GrandChild(); obj1.show(); } } |
GrandChild's show()
Overriding in Java
In Java, Overriding is a feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its super-classes or parent classes. When a method in a subclass has the same name, the same parameters or signature, and the same return type(or sub-type) as a method in its super-class, then the method in the subclass is said to override the method in the super-class.
Method overriding is one of the ways by which Java achieves Run Time Polymorphism. The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed. In other words, it is the type of the object being referred to (not the type of the reference variable) that determines which version of an overridden method will be executed.