Method Overriding in Java is used to achieve runtime polymorphism and dynamic behavior. In this chapter, we will learn about the method overloading, rules to implement with the help of examples.
Method Overriding allows a subclass to provide its own specific implementation of a method that is already defined in its parent class. Method overriding supports runtime polymorphism by enabling dynamic method binding, where the method call is resolved at runtime based on the actual object type.
The following points describe the uses of method overriding in Java:
The following are the important rules of method overriding in Java:
Let's understand the problem that we may face in the program if we do not use method overriding.
Output:
Vehicle is running
Explanation
We construct an instance of the Bike class and use it to invoke the run() method within the Bike class. As a result of Bike deriving from Vehicle, the run() function of the Vehicle class is overridden in the Bike class, resulting in the print "Vehicle is running" when the method is used on a Bike object. It demonstrates how method overriding, in which the method specified in the subclass overrides the method in the superclass with the identical signature, can result in polymorphic behaviour.
In this example, we have defined the run() method in the subclass Bike and the same method also defined in in the parent class i.e. Vehicle, but it has some specific implementation. The method's name and parameters are the same, and there is an IS-A relationship between the classes, so there is method overriding.
Output:
Bike is running safely
Explanation
A method in a subclass (Bike) overrides the same method in its superclass (Vehicle), as this Java program illustrates. The run() method in this example is shared by both types, but the Bike class implements it differently, outputting "Bike is running safely." The overridden function in the Bike class gets executed when we create an instance of Bike and use the run() method on it, proving that the implementation of the subclass takes precedence over the implementation of the superclass. It demonstrates how Java's dynamic polymorphism feature allows methods with the same signature to behave differently in various classes, even if they are part of the same inheritance tree.
Consider a scenario where Bank is a class that provides functionality to get the rate of interest. However, the rate of interest varies according to banks. For example, SBI, ICICI and AXIS banks could provide 8%, 7%, and 9% rate of interest.

Output:
SBI Rate of Interest: 8 ICICI Rate of Interest: 7 AXIS Rate of Interest: 9
Explanation
This Java programme uses a real-world scenario where three classes-SBI, ICICI, and AXIS-override a method from their parent class, Bank, to demonstrate the idea of method overriding. The getRateOfInterest() function of the Bank class yields 0. With their own implementation, each of the child classes overrides this method: SBI returns 8, ICICI returns 7, and AXIS returns 9. Each child class object is created in the Test2 class, and then each object's getRateOfInterest() method is used to print out the corresponding interest rates for each bank. This illustrates how polymorphic behaviour dependent on the type of object at runtime is made possible by method overriding, which enables each subclass to give its own implementation of a method inherited from the superclass.
Static methods cannot be overridden in Java. When a subclass declares a static method with the same signature as a static method in its superclass, it does not override the method; instead, it hides the superclass method. As a result, the method that gets executed is determined at compile time based on the reference type, not at runtime based on the actual object type. Therefore, static methods do not support runtime polymorphism like instance methods.
Method overriding is based on dynamic method dispatch, where the method call is resolved at runtime according to the actual object. However, static methods are associated with the class itself, not with individual objects, and hence they are resolved at compile time. Because of this, static methods are not eligible for dynamic dispatch and cannot be overridden.
Additionally, there is a difference in how static and instance methods are handled in memory. Instance methods are invoked through objects and are tied to the heap memory, while static methods are stored in the method area of the JVM and are shared among all instances of the class. Due to these fundamental differences in behavior, binding, and memory allocation, static methods cannot participate in method overriding.
The main() method in cannot be overridden because it is declared as static. The main() method is defined as public static void main(String[] args) and serves as the entry point of program execution.
Static methods belong to the class, not to objects, so they do not support runtime polymorphism. They are resolved at compile time, which makes method overriding impossible. Therefore, even if a subclass defines a main() method with the same signature, it does not override the superclass method, and the main() method cannot be overridden in Java.
The following table shows the demonstrate the difference between Method Overloading and Method Overriding:
| Aspect | Method Overloading | Method Overriding |
|---|---|---|
| Purpose and Intent | Method overloading is used to increase the readability of the program. | Method overriding is used to provide the specific implementation of the method that is already provided by its superclass. |
| Relationship between Classes | Method overloading is performed within class. | Method overriding occurs in two classes that have IS-A (inheritance) relationship. |
| Parameter Requirements | In case of method overloading, parameters must be different. | In case of method overriding, parameters must be the same. |
| Polymorphism Type | Method overloading is the example of compile-time polymorphism. | Method overriding is the example of runtime polymorphism. |
| Return Type Constraints | In Java, method overloading can't be performed by changing the return type of the method only. Return type can be the same or different in method overloading, but you must have to change the parameter. | Return type must be the same or covariant in method overriding. |
| Access Modifiers | It can have any access modifier. | The overriding method cannot have a more restrictive access modifier than the overridden method. |
| Exceptions | It can throw any exceptions. | It throws only checked exceptions declared in the superclass method or its subclasses. |
| Invocation | It resolved at compile-time. | It resolved at runtime using dynamic method dispatch. |
| Inheritance Required | Not required. | Required (through subclassing or interface implementation). |
| Binding | It uses static binding. | It uses dynamic binding. |
| Early and Late Binding | It is also known as early binding. | It is also known as late binding. |
| Signature Matching | Method signatures must be different. | Method signatures must be identical. |
| Statis Method | Static method can be overloaded. | Static method cannot be overridden. |
| Final and Public Method | It is applicable to both private and final methods. | It is not applicable to private and final methods. |
| Error | If any error occurs, can be caught at compile-time. | If any error occurs, can be caught at run-time. |
If you are overriding any method, overridden method (i.e. declared in subclass) must not be more restrictive.
Let us take an example to demonstrate the Access Modifiers with Method Overriding in Java.
Output:

Explanation
Class A declares a method called msg() with the protected access modifier in the provided Java code. By extending class A, class Simple aims to replace the message() function with a default access modifier. But because the default access modifier is more restricted than protected, this leads to a compile-time error. When overriding a method in Java, the overridden method's access level in the subclass needs to be at least as liberal as the method's access level in the superclass. Thus, in order to fix the issue, either the class Simple method's access modifier-such as protected or public-should be as liberal as protected, or the class A method should have a less permissive access modifier-such as default or public.
We request you to subscribe our newsletter for upcoming updates.