devnotes.

Method Overriding

Method overriding happens when a subclass provides its own implementation of a method that's already defined in its parent class, replacing (or extending) the inherited behavior for objects of that subclass.

class Bird {
    function move() {
        return "The bird flies."
    }
}

class Penguin extends Bird {
    function move() { // overrides Bird's move()
        return "The penguin swims (can't fly)."
    }
}

bird = new Bird()
penguin = new Penguin()

print(bird.move())     // "The bird flies."
print(penguin.move())  // "The penguin swims (can't fly)."

Extending rather than fully replacing parent behavior is common — call the parent's version explicitly and add to it:

class Logger {
    function log(message) {
        print("[LOG] " + message)
    }
}

class TimestampedLogger extends Logger {
    function log(message) {
        super.log(currentTime() + " — " + message) // calls the parent's version, adds a timestamp
    }
}

Rules that typically apply to overriding (specifics vary slightly by language):

  • The method name and parameter list (signature) must match the parent's exactly
  • The overriding method generally cannot reduce visibility (you can't override a public method with a private one)
  • Some languages require an explicit @Override annotation (Java) or override keyword (C#) to catch accidental typos that would otherwise silently create a brand-new method instead of actually overriding the intended one
  • A method marked final (or equivalent) cannot be overridden at all — used to lock in behavior that must never change in a subclass

Overriding is the mechanism that makes runtime polymorphism (covered in the Polymorphism chapter) possible in the first place.

Method Overriding in OOP Explained | DevNotes