How To Override A Method Java

8 min read

How to Override a Method in Java: A practical guide

Method overriding is a fundamental concept in Java that enables runtime polymorphism, allowing objects of different classes to be treated through a common interface. This powerful feature lets a subclass provide a specific implementation of a method that is already defined in its superclass, enhancing flexibility and code reusability in object-oriented programming That alone is useful..

Understanding Method Overriding

Method overriding occurs when a subclass defines a method with the same signature (name, parameter list, and return type) as a method in its superclass. The overriding method can have a covariant return type (a subclass of the original return type) but must maintain the same method signature otherwise. This mechanism allows the Java Virtual Machine (JVM) to dynamically select the appropriate method to execute based on the actual object type rather than the reference type No workaround needed..

Prerequisites for Method Overriding

Before diving into the steps, ensure you understand these key concepts:

  • Inheritance: Method overriding requires a subclass to inherit from a superclass
  • Access Modifiers: The overriding method cannot have a more restrictive access modifier than the original method
  • Static Methods: Static methods cannot be overridden, only hidden

Step-by-Step Guide to Method Overriding

Step 1: Create a Superclass with a Method

First, define a superclass containing the method you intend to override. This method should be marked as public, protected, or have package-private access (if the subclass is in the same package).

public class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

Step 2: Create a Subclass that Extends the Superclass

Next, create a subclass that inherits from the superclass using the extends keyword.

public class Dog extends Animal {
    // Override the makeSound method here
}

Step 3: Override the Method with the Same Signature

Inside the subclass, define a method with the exact same signature as the parent method. Use the @Override annotation to indicate that this method is intended to override the parent method.

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

Step 4: Test the Method Overriding

Create instances of both the superclass and subclass to observe the runtime polymorphism behavior Small thing, real impact..

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal dog = new Dog();
        
        animal.makeSound(); // Outputs: Animal makes a sound
        dog.makeSound();    // Outputs: Dog barks
    }
}

Rules and Best Practices for Method Overriding

Access Modifiers

The overriding method can have the same or less restrictive access modifier:

  • If the parent method is public, the child method must be public
  • If the parent method is protected, the child method can be protected or public
  • Package-private methods can only be overridden by classes in the same package

Return Types

The overriding method can return a covariant return type—a subclass of the original return type:

public class Animal {
    public Animal getAnimal() {
        return new Animal();
    }
}

public class Dog extends Animal {
    @Override
    public Dog getAnimal() {
        return new Dog();
    }
}

Exceptions

The overriding method cannot throw new checked exceptions that are not declared in the parent method, though it can throw fewer or narrower exceptions Still holds up..

The @Override Annotation

Always use the @Override annotation when overriding methods. This provides compile-time verification that the method signature matches a parent method, preventing accidental method hiding Nothing fancy..

Common Pitfalls and How to Avoid Them

Method Hiding vs. Overriding

Static methods are hidden, not overridden. When you define a static method in a subclass with the same signature as a static method in the parent class, the subclass method hides the parent method rather than overriding it And that's really what it comes down to. Simple as that..

public class Parent {
    public static void staticMethod() {
        System.out.println("Parent static method");
    }
}

public class Child extends Parent {
    // This hides the parent method, not overrides it
    public static void staticMethod() {
        System.out.println("Child static method");
    }
}

Final Methods

Methods marked as final in the superclass cannot be overridden by subclasses.

Final Classes

Classes marked as final cannot be subclassed, making method overriding impossible.

Advanced Method Overriding Scenarios

Overriding with Different Parameter Lists

If a subclass defines a method with the same name but different parameters, this is method overloading, not overriding. Both methods can coexist in the same class hierarchy.

Overriding Abstract Methods

Abstract methods must be overridden by concrete subclasses, providing a complete implementation of the method signature.

public abstract class Shape {
    public abstract double calculateArea();
}

public class Circle extends Shape {
    private double radius;
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

Practical Examples and Use Cases

Real-World Scenario: Polymorphic Collections

Method overriding enables polymorphic behavior in collections, allowing different subclasses to be stored in the same collection type:

List animals = new ArrayList<>();
animals.add(new Dog());
animals.add(new Cat());
animals.add(new Bird());

for (Animal animal : animals) {
    animal.makeSound(); // Each animal makes its own sound
}

Template Method Pattern

The template method pattern uses method overriding to define the skeleton of an algorithm, allowing subclasses to override specific steps:

public abstract class DataProcessor {
    public final void process() {
        readData();
        transformData();
        saveData();
    }
    
    protected abstract void readData();
    protected abstract void transformData();
    protected abstract void saveData();
}

public class CSVProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.Because of that, println("Transforming CSV data");
    }
    
    @Override
    protected void saveData() {
        System. But println("Reading CSV data");
    }
    
    @Override
    protected void transformData() {
        System. out.On top of that, out. out.

## FAQ: Common Questions About Method Overriding

**Q: What is the difference between method overriding and method overloading?**
A: Method overriding occurs when a subclass provides a specific implementation of a method defined in its superclass, using the same method signature. Method overloading occurs when multiple methods in the same class have the same name but different parameters.

**Q: Can we override a private method?**
A: No, private methods are not visible to subclasses, so they cannot be overridden. Attempts to "override" them will create a new method in the subclass rather than overriding the parent method.

**Q: What happens if we don't use the @Override annotation?**
A: The code will still compile and run correctly if the method signature matches, but the annotation provides compile-time verification and improves code clarity.

**Q: Can we override a method that throws exceptions?**
A: Yes, but the overriding method cannot throw checked exceptions that are broader or new compared to the parent method. It can throw narrower exceptions or no exceptions at all.

**Q: How does method overriding relate to polymorphism?**
A: Method overriding is the mechanism that enables runtime polymorphism in Java. It allows the JVM to select the appropriate method implementation based on the actual

based on the actual object type at runtime, which is why the same method call can yield different behavior depending on whether the reference points to a Dog, a Cat, or a Bird.

### Covariant Return Types and Overriding
Starting with Java 5, an overriding method may return a subtype of the return type declared in the superclass. This feature, known as covariant return types, lets you narrow the return type without breaking the contract:

```java
abstract class Animal {
    abstract Animal getOffspring();
}

class Dog extends Animal {
    @Override
    Dog getOffspring() {   // returns Dog, a subtype of Animal
        return new Dog();
    }
}

Covariant returns are particularly useful when you want the overridden method to provide a more specific result while still satisfying the supertype’s signature Practical, not theoretical..

Overriding and Interface Default Methods

Java 8 introduced default methods in interfaces. A class that implements an interface can override a default method to provide its own implementation, just as it would override a method from a superclass:

interface Flyable {
    default void fly() {
        System.out.println("Flying with generic wings");
    }
}

class Sparrow implements Flyable {
    @Override
    public void fly() {
        System.out.println("Sparrow flutters quickly");
    }
}

When a class inherits both a superclass method and an interface default method with the same signature, the class’s own implementation (if any) takes precedence; otherwise, the superclass method wins over the interface default.

Final Methods and the Liskov Substitution Principle

Marking a method as final prevents overriding altogether. This is a deliberate design choice when the method’s behavior is integral to the class’s contract and must remain unchanged in all subclasses. Adhering to the Liskov Substitution Principle (LSP) means that any overridden method should preserve the expectations set by the superclass: preconditions cannot be strengthened, postconditions cannot be weakened, and invariants must be maintained. Violating LSP can lead to subtle bugs when polymorphic code assumes the superclass’s behavior.

Best Practices for Method Overriding

  1. Always use @Override – it catches mismatched signatures at compile time.
  2. Keep the method’s contract intact – do not change checked exception lists to broader types, and respect the semantics documented in the superclass.
  3. Prefer immutability where possible – if the superclass method relies on immutable state, overriding should not introduce mutable side effects that break thread‑safety guarantees.
  4. Document intentional changes – when you deliberately narrow a return type or throw a more specific exception, annotate the override with a comment explaining why.
  5. Avoid overriding private or static methods – such attempts create new methods rather than true overrides, leading to confusion.

Conclusion

Method overriding is the cornerstone of runtime polymorphism in Java, enabling a single method call to invoke different implementations based on the actual object instance. By understanding the rules—signature matching, access modifiers, return type covariance, exception handling, and the interplay with interfaces and final methods—you can design flexible, maintainable class hierarchies that honor the Liskov Substitution Principle. Proper use of the @Override annotation, thoughtful documentation, and adherence to contractual guarantees make sure overriding enhances, rather than undermines, the robustness of your code. When applied judiciously, overriding empowers developers to build extensible frameworks where new behaviors can be added simply by extending existing classes, all while preserving a uniform interface for clients.

Up Next

Hot off the Keyboard

Worth Exploring Next

You Might Find These Interesting

Thank you for reading about How To Override A Method Java. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home