• Articles
  • Tutorials
  • Interview Questions

Overriding in Java

Overriding in Java

In this blog, you will explore everything about method overriding in Java. Firstly, we will discuss what it is and why it is used, with the help of examples. Afterwards, we will discuss the necessary conditions to be followed in order to override a method. Moreover, we will also discuss exception handling with overriding in Java.

Table of Contents:

To improve your Java skills and start coding like a pro, watch our YouTube video!

Video Thumbnail

What is Overriding in Java?

Method overriding in Java refers to the capability of a subclass or child class to provide a specific implementation for an already defined method in its base class or parent class. When a subclass has a method with the same name, return type, and parameters as a method in its base class, it is said to override that method. This allows the subclass to provide its own version of the method, modifying the behavior to suit its specific needs. When an object of the subclass invokes the overridden method, the customized implementation in the subclass will be executed instead of the original implementation in the base class. In other words, when the subclass overrides a method, it retains the method signature but provides its own implementation.

Are you ready to advance your Java knowledge? Enroll in our thorough Java course today to maximize your potential!

Why is Overriding Used in Java?

Method overriding enables Java to accept runtime polymorphism. In simple words, method overriding allows subclasses to implement their own definition of methods inherited from a parent class. This dynamic feature allows developers to customize how methods work, making them more flexible and encouraging the reuse of code. It makes sure that related classes have a uniform way of interacting, and it helps the program decide which method to use as the program runs, leading to the development of software systems that are adaptable and responsive. Overridden methods enable the calling of methods from any object of a derived class without the need to identify the specific modifications made in the superclass.

Get 100% Hike!

Master Most in Demand Skills Now!

Example of Overriding in Java

Let’s understand the concept of overriding with an example. We will create a method in the parent class and then override that method in the child class. It is important to note that there can be more than one child class, which overrides the parent class.

// Importing required libraries
import java.io.*;
// Parent or Base Class
class Shape {
    double area() {
        System.out.println("area() method of base class");
        return 0.0; // Default area for a generic shape
    }
}
// Inherited Class: Circle
class Circle extends Shape {
    public double radius;
    // Constructor
    Circle(double radius) {
        this.radius = radius;
    }
    // Overriding the area method for circles
    double area() {
        System.out.println("area() method of Circle class");
        return Math.PI * radius * radius; // Area of a circle
    }
}
// Inherited Class: Triangle
class Triangle extends Shape {
    public double base;
    public double height;
    // Constructor
    Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    // Overriding the area method for triangles
    double area() {
        System.out.println("area() method of Triangle class");
        return 0.5 * base * height; // Area of a triangle
    }
}
public class Main {
    // Main Function
    public static void main(String args[]) {
        Circle circle = new Circle(5.0);
        Shape genericShape = new Shape();
        // Calculating area for Circle
        System.out.println("Area of Circle: " + circle.area());
        // Calculating area for genericShape
        System.out.println("Area of Generic Shape: " + genericShape.area());
        // Using polymorphism to create an instance of Circle
        Shape shape = new Circle(3.0);
        // area() method of Shape class is overridden by
        // Circle class area()
        System.out.println("Area of Shape (Circle): " + shape.area());
        // Creating an instance of Triangle
        Triangle triangle = new Triangle(4.0, 6.0);
        // Calculating area for Triangle
        System.out.println("Area of Triangle: " + triangle.area());
    }
}

Output:

area() method of Circle class

Area of Circle: 78.53981633974483

area() method of base class

Area of Generic Shape: 0.0

area() method of Circle class

Area of Shape (Circle): 28.274333882308138

area() method of Triangle class

Area of Triangle: 12.0

In this example, there are two child classes, namely circle and triangle. Each class extends the base class `Shape` and overrides the area() method to provide a specific implementation for calculating its area. The name of the function is the same, but the function definition or implementation is different in both classes because the formulas for calculating the area of a circle and a triangle are different.

Inside the “main” class,  objects of “circle”, “triangle”, and “shape” are created, and their respective areas are calculated and printed. The output includes messages from the overridden area() methods, illustrating the specific behavior for each shape type.

This example demonstrates the concept of OOPs, including inheritance, overriding, and polymorphism. It highlights how a common interface can be shared among different shapes, allowing for ease of extension to accommodate additional shapes in the future.

Want to ace your next Java interview? Check out our recent blog post about the most common Java interview questions and answers!

Rules for Overriding a Method in Java

In Java, when overriding a method in a subclass, certain rules should be followed to ensure smooth code execution. Here are the key rules for method overriding:

  • Method Signature: The overriding method in the subclass must have the same method signature (name, return type, and parameters) as the overridden method in the superclass.
  • Access Modifier: The access level of the overriding method cannot be more restrictive than the overridden method. For example, if the superclass method is declared as public, the subclass method cannot be private.
  • Return Type: This must be the same as, or a subtype of, the return type of the overridden method. Covariant return types are allowed starting with Java 5.
  • Static Methods: Overridden methods cannot be static, but they can be hidden by a static method in the subclass with the same signature. This is known as method hiding.
  • Final Methods: Final methods in the superclass cannot be overridden in the subclass.
  • Abstract Methods: If a subclass is not abstract, it must provide an implementation for all abstract methods inherited from its abstract superclass.
  • Constructors: Constructors cannot be overridden in Java.

Get a Complete Hands-on on Java through our Java Project Tutorial.

Exception Handling with Overriding in Java

An exception is an unexpected event that happens while a program is running, causing a disturbance in its usual process. Exception handling comes into play to manage these unexpected issues during runtime. However, when we mix exception handling with method overriding, things can get a bit tricky. The computer, or compiler, can get confused about which method definition to follow because of the different ways methods are defined. This situation is known as ambiguity.

When it comes to exception handling in method overriding, there are two simple rules to follow. Those rules are as follows:

  • If the original method in the parent class doesn’t mention any exceptions, the new method in the child class can only mention unchecked exceptions.
  • If the parent class declares any exception and the child class declares the same exception or no exception.

These rules help keep things clear and avoid confusion when dealing with exceptions in overridden methods.

Let’s see the examples, starting where the parent class doesn’t mention any exceptions and the subclass mentions checked exceptions:

import java.io.*;
class Parent {
    void performTask() {
        System.out.println("Task performed in Parent class");
    }
}
class Child extends Parent {
    // Overridden method declaring a checked Exception (IOException)
    void performTask() throws IOException {
        System.out.println("Task performed in Child class");
        throw new IOException("IOException in Child class");
    }
}
public class Main {
    public static void main(String[] args) {
        Parent parent = new Child();
        try {
            parent.performTask(); // This will result in a compilation error as the overridden method declares a checked exception.
        } catch (IOException e) {
            System.err.println("Caught IOException: " + e.getMessage());
        }
    }
}

In this example, the “Parent” class has the method “performTask” without mentioning any exceptions. The “Child” class overrides this method and mentions a checked exception (`IOException`). When calling the overridden method using a “Parent” reference pointing to a “Child” object, it results in a compilation error, and the code needs to handle the checked exception using a “try-catch” block.

The output of this example will be:

Main.java:11: error: performTask() in Child cannot override performTask() in Parent

    void performTask() throws IOException {

         ^

  overridden method does not throw IOException

Now see the following example for the second case where there is no exception in parent class and unchecked exception in the child class:

import java.io.*;
class Parent {
    void performTask() {
        System.out.println("Task performed in Parent class");
    }
}
class Child extends Parent {
    // Overridden method declaring an Unchecked Exception (ArithmeticException)
    void performTask() throws ArithmeticException {
        System.out.println("Task performed in Child class");
        throw new ArithmeticException("ArithmeticException in Child class");
    }
}
public class Main {
    public static void main(String[] args) {
        Parent parent = new Child();
        parent.performTask(); // This will work fine as the overridden method in Child declares an unchecked exception.
    }
}

In this example, the “Parent” class has a  method performTask without mentioning any exceptions. The Child class overrides this method and mentions an unchecked exception (ArithmeticException). When calling the overridden method using a “Parent” reference pointing to a “Child” object, it works without any compilation error since unchecked exceptions don’t need to be declared or caught.

The output for this program will be:

Task performed in Child class

Exception in thread “main” java.lang.ArithmeticException: ArithmeticException in Child class

    at Child.performTask(Main.java:12)

    at Main.main(Main.java:18)

Learn the essential Spring Interview Questions and Answers to ace your next interview!

Conclusion

Overall, method overriding in Java facilitates the creation of robust and adaptable software systems, supporting good software engineering practices. It has greatly simplified programming by introducing polymorphism, allowing a single method name to represent diverse implementations across different classes. Developers can reuse methods from a superclass in subclasses, contributing to a modular “write once, use many times” approach. Method overriding supports dynamic binding, making runtime decisions about which method to call, and ensures consistent interfaces across related classes.

Course Schedule

Name Date Details
Python Course 23 Nov 2024(Sat-Sun) Weekend Batch View Details
30 Nov 2024(Sat-Sun) Weekend Batch
07 Dec 2024(Sat-Sun) Weekend Batch

About the Author

Senior Consultant Analytics & Data Science

Sahil Mattoo, a Senior Software Engineer at Eli Lilly and Company, is an accomplished professional with 14 years of experience in languages such as Java, Python, and JavaScript. Sahil has a strong foundation in system architecture, database management, and API integration.