Overriding in Java

Overriding in Java

Overriding is a core concept of Object Oriented Programming and is directly linked with the feature of Inheritance. Overriding is a feature that allows sub classes to implement functionalities to methods of its own of the same name as that of its super class. In simpler words, if a method is already defined in a super class, when a sub class extends it, it can declare a method by the same name and the new method formed in the subclass will be called during method call. Overriding in Java is defined to occur ‘when a method in a subclass has the same name, same parameters or signature, and same return type (or sub-type) as a method in its super-class’. The method of the subclass overrides the method of the superclass.

Example: Pseudo Code

Animal (Parent Class)
{
data..
move() //Method of the superclass
eat() //Method of the superclass
}
Dog extends Animal
{
data..
move() //Overrides the move() method of the parent class.
bark() //Method of the subclass

 

The feature of method overriding is commonly used to achieve Java Run-time polymorphism. During method class, which version of the method will be called will only depend upon the type of object, that is whether it is an object of the parent class or the sub class. If an object of the parent class is used to call the method, the parent class version of the method will be invoked. If an object of the sub classis used to call the method, then the sub class method will be invoked overriding the parent class version. Therefore, rather than the type of the reference variable, it is the type of the object that is used to determine which method will be invoked and which method will be overridden.

Sample Code

The following code will demonstrate a simple example of method overriding.

//Parent Class
class Parent
{
void show ()
{
System.out.println (“Parent’s show ()”);
}
}
//Sub class
class Child extends Parent
{
@override
void show ()
{
System.out.println (“Child’s Show”);
}
}
//The Main Class
class Main
{
public static void main (String args [])
{
Parent obj1 = new Parent ();
obj1.show ();
Parent obj2 = new Child ();
obj2.show();
}
}

 

OUTPUT

Parent’s Show
Child’s Show

Rules for Overriding Methods

1. Overriding and Access Modifiers

In no way can the access modifier reduce the scope for an overriding method. It can however, allow greater scope if chosen accordingly. For example, if you have a protected instance method in the super class, you can make it public in the subclass but you cannot make it private. Therefore, you cannot further reduce the scope and restrict it only to the current class. This will lead to a compile time error.

Sample Code

class Parent
{
private void m1()
{
System.out.println (“From parent m1()”);
}
protected void m2 ()
{
System.out.println (“From parent m2 ()”);
}
}
class Child extends Parent
{
private void m1 ()
{
System.out.println (“From Child m1 ()”);
}
@Override
public void m2 ()
{
System.out.println (“From child m2 ()”);
}
}
//Main Class
class Main
{
public static void main (String args [])
{
Parent obj1 = new Parent ();
obj1.m2 ();
Parent obj2 = new Child ();
obj2.m2 ();
}
}

 

OUTPUT
From parent m2 ()
From child m2 ()

2. Final Methods cannot be overridden

Any method that has bee declared final in the super class, cannot be overridden in the sub class. This can also be thought of as a technique you can implement when you do not want a particular method in the super class to be overridden in the sub class.

//A sample code to show that final methods cannot be overridden
class Parent
{
final void show()
{
}
}
class Child extends Parent
{
void show ()
{
}
}

 

OUTPUT

13: error: show () in Child cannot override show () in Parent
void show () {   }
overridden method is final

 

3. Static Methods cannot be overridden

This brings us to the difference between method overriding and method hiding. When a static method is defined with the same, signature, and argument list of that of a super class, this feature is called method hiding rather than overriding. The following table summarizes overriding better:

 Superclass Instance MethodSuperclass Static Method
Subclass Instance MethodOverridesGenerates Compile time error
Subclass Static MethodGenerates Compile-time errorMethod Hiding takes place.

 

class Parent
{
static void m1 ()
{
System.out.println ( “From parent” + “static m1 ()” );
}
void m2 ()
{
System.out.println (“From parent” + “non-static (instance) m2”);
}
}
class Child extends Parent
{
static void m1 ()
{
System.out.println (“From child static m1 ()”);
}
//This method overrides m2 of parent class
@Override
public void m2 ()
{
System.out.println (“From child” + “non static (instance) m2 ()”);
}
}
//The main class
class Main
{
public static void main (String args [])
{
Parent obj1 = new Child ();
obj1.m1 ();
obj1.m2 ();
}
}

 

OUTPUT
From parent static m1 ()
From child non-static (instance) m2 ()

4. Private Methods cannot be overridden

The private access modifier restricts the scope of the program entities only to that particular entity. Therefore, it is not possible to override a private method in a subclass as the scope of the method will only exists inside the parent class.

5. The overriding method must have the same return type or subtype

For a long time, Java did not allow subclasses overriding a method of a parent class to have a different return type. However, from Java 5.0, overriding methods in the sub class can have return types different from the overridden method but it has to be a subtype of the return type of the overridden method. This is also called covariant return type.

6. Invoking overridden method from sub-class

If you want to specifically call the overridden method of the parent class from the subclass, you can do so using the super keyword as follows:

class Parent
{
void show ()
{
System.out.println (“Parent’s show ()”);
}
}
class Child extends Parent
{
@Override
void show ()
{
super.show ()
System.out.println ( “Child’s show ()”);
}
}
//Main Class
class Main
{
public static void main (String args [])
{
Parent obj = new Child ();
obj.show ();
}
}

 

OUTPUT

Parent’s Show
Child’s Show

7. Constructor Overriding

The constructor of the super class can never be overridden in a sub class. This is because the constructor is unique to every class and has the name of the class in its declaration. As subclasses have different names, it is not possible.

8. Overriding and Exception – Handling

There are two rules that are pertinent to exception handling when it comes to method overriding. They are as follows:

  1. Rule 1: When the super class version of the method does not throw any exception, the only exception that the overriding method can throw is the unchecked exception. It cannot throw a checked exception as that will lead to a compile time error.
    class Parent
    {
    void m1 ()
    {
    out.println (“From parent m1 ()”);
    }
    void m2 ()
    {
    System.out.println (“From parent m2 ()”);
    }
    }
    class Child extends Parent
    {
    @Override
    void m1() throws ArithmeticException
    {
    System.out.println (“From child m1 ()”);
    }
    @override
    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

  2. Rule 2: If in case the overridden method in the parent class does throw an exception, the overriding method in the sub class can only throw the same subclass exception. If it throws a parent exception in Exception hierarchy, a compile time error will be faced with. The best case is when the sub class version of the method does not throw any exception at all.
    class Parent
    {
    void m1 () throws RunTimeException
    {
    out.println (“From parent m1 ()”);
    }
    }
    class Child1 extends Parent
    {
    @Override
    void m1 () throws RuntimeException
    {
    System.out.println (“From child m1 ()”);
    }
    class Child2 extends Parent
    {
    @Override
    void m1 () throws ArithmeticException
    {
    System.out.pritln (“From child2 m1 ()”);
    }
    }
    class Child3 extends Parent
    {
    @Override
    void m1 ()
    {
    System.out.println (“From child3 m1 ()”);
    }
    }
    class Child4 extends Parent
    {
    @Override
    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

9. Overriding and Abstract Methods

Abstract methods are generally method declarations without any significant method body. Methods of these types are generally meant to be overridden in the sub class. In simpler words, abstract methods are contained in the superclass which are then overridden in the subclasses otherwise, the code runs into compile time errors.

10. Overriding and synchronized/strictfp method

Synchronized /strictfp methods do not have any effect on the rules of overriding. Therefore, it is possible for a synchronized/strictfp method to override a non synchronized/strictfp method.

Sample Code to show Multi-level method overriding

class Parent {
void show ()
{
System.out.println (“parent’s show ()”);
}
}
class Chilld extends Parent
{
void show ()
{
System.out.println ( “Child’s show ()”);
}
class Grandchild extends Child
{
void show ()
{
System.out.println (“Grandchild’s show ()”);
}
}
//The main class
class Main
{
public static void main (String args [])
{
Parent obj1 = new Grandchild ();
obj1. show ();
}
}

 

OUTPUT
Grandchild’s show ()

Overriding vs Overloading

  • Overloading refers to declaring more than one method with the same method name but different parameter lists. While overloading deals with different methods, overriding deals with the same method being overridden in a subclass connected through inheritance.
  • Overloading is an example of compile time polymorphism while overriding is an example of run-time polymorphism.

Why Method Overriding?

As mentioned above, method overriding allows Java to implement run time polymorphism. Polymorphism is a very important part of Java as it gives the option to users to declare methods in a super class and specify the functionalities in the sub classes. The ‘one interface, multiple methods’ concept is a direct derivate of method overriding.

To enable reusability and robustness of code, Java uses a very powerful tool called Dynamic Method Dispatch. The ability to existing code libraries to call methods on instances of newly created classes is a very big boon to the programming language.

One major advantage of applying this technique of method overriding is that it allows us to call methods without even knowing the type of the method in the derived objects that are being used to call the methods in the first place.

When to Apply Overriding?

The key to using method overriding properly is to understand the dynamics of inheritance which is comprised of a super class that is extended or inherited by a sub class. The flow of inheritance moves from lesser specialization in superclasses to greater specializations in the sub classes. The main aim should be such that the superclass has all the ingredients needed to cook a particular dish. The subclass will use the ingredients from the super class to cook the food it wants inside its own method.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.