Method Overriding in Java

Method overriding in Java happens when a subclass provides its own implementation for an inherited instance method with the same method signature. It is one of the main ways to achieve Polymorphism in Java, because the method that runs is chosen at runtime based on the actual object.

In this tutorial, we shall learn overriding in Java with example programs, rules, common mistakes, use of the @Override annotation, the difference between method overriding and method overloading, and cases where a method cannot be overridden.

In context of sub-class extending a super-class, the sub-class can access super-class’s methods. If in case the sub-class wants functionality of an existing method in Super Class to be replaced by some specific implementation, then Java provides the ability to override the existing functionality through Method Overriding. It can also be thought of as Runtime Polymorphism.

How Method Overriding Works in Java Inheritance

When a superclass reference points to a subclass object, Java uses dynamic method dispatch for overridden instance methods. This means the method body is selected from the actual object type, not only from the reference variable type.

</>
Copy
Car vehicle = new Audi();
vehicle.accelerate();   // calls Audi's overridden accelerate() method

The compiler checks that accelerate() is available in the Car type, but at runtime the implementation in Audi is executed because the object is an Audi.

Rules for Method Overriding in Java

Following are the rules for implementing Method Overriding in Java.

  1. The method declaration should be same as that of the method that is to be overridden.
  2. The class (sub class) should extend another class (super class), prior to even try overriding.
  3. Sub Class can never override final methods of Super Class.

In addition to the basic rules above, keep these Java overriding rules in mind.

  • Same method name and parameter list: the overriding method must have the same method signature as the superclass method.
  • Compatible return type: the return type must be the same or a subtype of the original return type. This is called a covariant return type.
  • Access cannot be more restrictive: for example, a public superclass method cannot be overridden as protected or private.
  • Checked exceptions cannot be broader: the overriding method cannot throw a broader checked exception than the overridden method.
  • Only inherited instance methods are overridden: constructors are not inherited, and static methods are hidden, not overridden.

Example 1 – Method Overriding

We shall take an example scenario where Car is a super-class and Audi is a sub-class.

Following is the super class.

Car.java

</>
Copy
public class Car {

	public void brake(){
		System.out.println("break in Car");
	}
	
	public void accelerate(){
		System.out.println("accelerate in Car");
	}
}

Following is the sub class.

Audi.java

</>
Copy
public class Audi extends Car {

	public static void main(String[] args) {
		Audi audi = new Audi();
		audi.accelerate();
		audi.brake();
	}
}

Run the above program. You shall get the following output in console.

accelerate in Car
break in Car

In this first program, Audi extends Car but does not define its own accelerate() or brake() method. Therefore, both method calls use the inherited implementations from Car.

Sub Class Overriding Method of Super Class

Now we shall override accelerate method in Audi.java by overriding accelerate() in Car.java

Car.java

</>
Copy
public class Car {

	public void brake(){
		System.out.println("break in Car");
	}
	
	public void accelerate(){
		System.out.println("accelerate in Car");
	}
}

Audi.java

</>
Copy
public class Audi extends Car {

	public static void main(String[] args) {
		Audi audi = new Audi();
		audi.accelerate();
		audi.brake();
	}
	
	public void accelerate(){
		System.out.println("accelerate in Audi");
	}
}

Output

accelerate in Audi
break in Car

Here, Audi overrides only accelerate(). The brake() method is not defined in Audi, so Java still uses the inherited brake() method from Car.

Use @Override Annotation When Overriding Java Methods

The @Override annotation is not mandatory, but it is strongly recommended. It asks the compiler to verify that the method is really overriding a method from the superclass or interface. If the method name, parameters, or return type are wrong, the compiler reports the mistake.

</>
Copy
public class Audi extends Car {

    @Override
    public void accelerate() {
        System.out.println("accelerate in Audi");
    }
}

Without @Override, a small typing mistake may create a new method instead of overriding the intended method. With @Override, the error is caught during compilation.

Runtime Polymorphism with Method Overriding in Java

The following example shows why method overriding is also called runtime polymorphism. The reference variable is of type Car, but it points to an Audi object.

</>
Copy
public class MethodOverridingDemo {
    public static void main(String[] args) {
        Car car = new Audi();
        car.accelerate();
        car.brake();
    }
}
accelerate in Audi
break in Car

The call to accelerate() is resolved to Audi.accelerate() at runtime. The call to brake() is resolved to Car.brake() because Audi does not override that method.

Calling the Superclass Method from an Overridden Java Method

Sometimes the subclass should add extra behavior instead of completely replacing the superclass behavior. In that case, use super.methodName() inside the overriding method.

</>
Copy
class Vehicle {
    public void start() {
        System.out.println("Check fuel and battery");
    }
}

class ElectricCar extends Vehicle {
    @Override
    public void start() {
        super.start();
        System.out.println("Start electric motor");
    }

    public static void main(String[] args) {
        ElectricCar car = new ElectricCar();
        car.start();
    }
}
Check fuel and battery
Start electric motor

In this example, super.start() calls the start() method from Vehicle before the subclass adds its own message.

Method Overriding vs Method Overloading in Java

Method overriding and method overloading are often confused because both use methods with the same name. The difference is in where the methods are defined and how Java selects them.

FeatureMethod OverridingMethod Overloading
Where it happensBetween superclass and subclassUsually in the same class, but can also involve inherited methods
Method parametersMust be the sameMust be different in number, type, or order
Return typeSame or covariant return typeReturn type alone cannot overload a method
Polymorphism typeRuntime polymorphismCompile-time polymorphism
ExampleDog.sound() overrides Animal.sound()print(int) and print(String)

Java Methods That Cannot Be Overridden

Not every method-like member in a class can be overridden. The following cases are common in Java interviews and beginner programs.

  • final methods: cannot be overridden because final prevents replacement in subclasses.
  • static methods: are hidden when redeclared in a subclass; they are not overridden by runtime polymorphism.
  • private methods: are not inherited by subclasses, so they cannot be overridden.
  • constructors: are not methods and are not inherited, so they cannot be overridden.

Override final method of Super Class

Any method that is declared final in the Super Class cannot be overridden by Sub Class. If you try doing so, you may get an Error as shown in the following.

Car.java

</>
Copy
public class Car {

	public void brake(){
		System.out.println("break in Car");
	}
	
	public final void accelerate(){
		System.out.println("accelerate in Car");
	}
}

Audi.java

</>
Copy
public class Audi extends Car {

	public static void main(String[] args) {
		Audi audi = new Audi();
		audi.accelerate();
		audi.brake();
	}
	
	public void accelerate(){
		System.out.println("accelerate in Audi");
	}
}

Output

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: class Audi overrides final method accelerate.()V
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

In current Java development, this is normally caught by the compiler before the program runs. A typical compiler message says that the overridden method is final and cannot be overridden.

error: accelerate() in Audi cannot override accelerate() in Car
  overridden method is final

Static Method Hiding Is Not Java Method Overriding

If a subclass declares a static method with the same signature as a static method in the superclass, the method is hidden, not overridden. Static methods are resolved using the reference type.

</>
Copy
class Parent {
    static void display() {
        System.out.println("Parent static display");
    }
}

class Child extends Parent {
    static void display() {
        System.out.println("Child static display");
    }

    public static void main(String[] args) {
        Parent obj = new Child();
        obj.display();
    }
}
Parent static display

The object created is Child, but obj is a Parent reference. Because display() is static, Java uses the reference type and calls Parent.display().

Common Mistakes in Java Method Overriding

  • Changing the parameter list: this creates an overloaded method instead of overriding the superclass method.
  • Reducing visibility: changing a public method to protected, default, or private is not allowed.
  • Trying to override static methods: static methods are hidden, not overridden.
  • Forgetting @Override: the code may compile even when the intended override is not happening.
  • Confusing final classes and final methods: a final class cannot be extended, and a final method cannot be overridden.

When to Use Method Overriding in Java Programs

Use method overriding when a subclass should keep the same method contract as its superclass but provide a more specific implementation. Common examples include calculating area for different shapes, printing details for different employee types, or defining different sound behavior for different animals.

</>
Copy
class Shape {
    public double area() {
        return 0.0;
    }
}

class Circle extends Shape {
    private double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

The method name remains area(), so client code can work with the general Shape type while each subclass supplies its own calculation.

FAQs on Method Overriding in Java

What is method overriding in Java?

Method overriding in Java is the process where a subclass provides a specific implementation for an inherited instance method that has the same name, parameter list, and compatible return type as the method in the superclass.

What is the difference between method overriding and method overloading?

Method overriding happens between a superclass and subclass with the same method signature. Method overloading happens when methods have the same name but different parameter lists. Overriding supports runtime polymorphism, while overloading is resolved at compile time.

Why do we use method overriding in Java?

We use method overriding to let a subclass provide behavior that is specific to that subclass while keeping a common method name and structure defined by the superclass.

Can we override a final method in Java?

No. A method declared with the final keyword cannot be overridden in a subclass. The compiler prevents the subclass from replacing that method implementation.

Can we override a static method in Java?

No. Static methods are not overridden. If a subclass declares a static method with the same signature, it hides the superclass method instead of overriding it.

Editorial QA Checklist for Java Method Overriding Examples

  • Confirm that every overriding example uses the same method name and parameter list in the superclass and subclass.
  • Use @Override in new examples unless the example is intentionally demonstrating a mistake.
  • Check that output blocks match the exact System.out.println() statements in the code.
  • Do not describe static method hiding, constructor behavior, or private methods as overriding.
  • When showing a final method error, mention that modern Java compilers usually catch it before runtime.

Conclusion

In this Java Tutorial, we have learnt Method Overriding in Java with example programs, the pre-requisites to override a method.

Method overriding is useful when subclasses need specialized behavior while still following the structure provided by a superclass. The most important points are to match the method signature, avoid reducing access, use @Override, and remember that final, static, private methods, and constructors do not behave like normal overridden instance methods.

In our next tutorial, we shall learn about Final Keyword in Java.