Web Analytics

Method Overriding

Intermediate ~35 min read

Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its parent class. This is a key feature that enables runtime polymorphism in Java.

What is Method Overriding?

When a subclass defines a method with the same name, return type, and parameters as a method in its parent class, it overrides the parent's method. The subclass version is called instead of the parent version when invoked on a subclass object.

class Animal {
    void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    @Override  // Annotation indicating override
    void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}

The @Override Annotation

The @Override annotation tells the compiler that you intend to override a method from the parent class. While optional, it's highly recommended because:

  • The compiler will catch errors if the method doesn't actually override anything
  • It makes your code more readable and documents your intent
  • It catches typos in method names or incorrect parameter types
class Parent {
    void display() {
        System.out.println("Parent display");
    }
}

class Child extends Parent {
    @Override
    void display() {  // Correctly overrides
        System.out.println("Child display");
    }

    // @Override
    // void disply() { }  // Compiler error! "disply" doesn't exist in parent
}
Best Practice: Always use @Override when overriding methods. It's a free compile-time check that prevents bugs.

Rules for Method Overriding

For a method to correctly override a parent method:

  1. Same method name
  2. Same parameter list (number, type, and order)
  3. Same or covariant return type (subtype of parent's return type)
  4. Access modifier must be same or less restrictive
  5. Cannot override final, static, or private methods
class Parent {
    protected Number getValue() {
        return 10;
    }
}

class Child extends Parent {
    @Override
    public Integer getValue() {  // Valid: Integer is subtype of Number
        return 20;               // public is less restrictive than protected
    }
}

Dynamic Method Dispatch (Runtime Polymorphism)

When you call an overridden method using a parent type reference pointing to a child object, Java determines which version to call at runtime based on the actual object type. This is called dynamic method dispatch.

Java Method Overriding Diagram showing parent and child class method implementations
Animal animal1 = new Dog();   // Parent reference, Child object
Animal animal2 = new Cat();   // Parent reference, Child object

animal1.makeSound();  // Output: "Woof! Woof!" - Dog's method
animal2.makeSound();  // Output: "Meow!" - Cat's method

// The actual method called depends on the OBJECT type, not reference type

Overriding vs Overloading

Method Overriding Method Overloading
Same method signature in subclass Different parameters in same class
Requires inheritance (parent-child) Can be in same class
Resolved at runtime Resolved at compile time
Return type must be same or covariant Return type can be different
Used for runtime polymorphism Used for compile-time polymorphism
Output
Click Run to execute your code

What Cannot Be Overridden

  • final methods: Declared to prevent overriding
  • static methods: Belong to class, not instance (can be hidden, not overridden)
  • private methods: Not visible to subclass
  • Constructors: Not inherited, so cannot be overridden
class Parent {
    final void finalMethod() { }     // Cannot override
    static void staticMethod() { }   // Cannot override (can hide)
    private void privateMethod() { } // Cannot override (not visible)
}

Calling the Parent's Version

Use super.methodName() to call the parent's version of an overridden method.

class Employee {
    void work() {
        System.out.println("Working on general tasks");
    }
}

class Developer extends Employee {
    @Override
    void work() {
        super.work();  // Call parent's work() first
        System.out.println("Writing code");
    }
}

Common Mistakes

  • Changing parameter types: This creates overloading, not overriding
  • Using more restrictive access: Cannot make public method private in subclass
  • Forgetting @Override: Typos in method names go undetected
  • Trying to override static methods: Static methods are hidden, not overridden

Summary

  • Method overriding provides a new implementation of an inherited method
  • Use @Override annotation for compile-time safety
  • Same name, parameters, and compatible return type required
  • Access modifier must be same or less restrictive
  • Dynamic method dispatch determines which version to call at runtime
  • final, static, and private methods cannot be overridden