Start learning free

LESSON 183 OF 344 · OBJECT-ORIENTED PROGRAMMING

Method Overriding in JavaScript: Redefining Methods

Lesson Read the full explanation

TL ; DR:

When a child class defines a method with the same name as the parent's, the child's version overrides the parent's. Different objects can give the same method name different behavior.


class Dog {
    bark() { console.log("Woof!"); }
}
class Puppy extends Dog {
    bark() { console.log("Yip!"); }
}


Full lesson:

You've seen that a child class inherits the parent's methods. Overriding is what happens when the child wants to change one of those inherited methods.

Why override?

Subclasses are usually special cases of the parent. A Puppy is a Dog, but it sounds different — "Yip!" instead of "Woof!". Instead of inventing a new method name, you redefine bark() on the Puppy. Callers don't need to know which subclass they're holding — they just call bark() and the right version runs.

How it works in each language

  • C# — the parent method must be marked virtual, the child marks its replacement override. The compiler enforces this pairing.
  • Java — every non-final method is virtual by default; the @Override annotation is optional but tells the compiler to verify the signature matches.
  • Python — defining a method with the same name in the child class replaces the parent's. No keyword required.
  • JavaScript — same as Python: define the method again on the child class and it wins.
  • C++ — the parent method must be virtual; override on the child is optional but compiler-checked.

Your task

The Dog class already defines bark. Inside the Puppy subclass, override bark so it prints "Yip! I am " followed by the puppy's name. The harness creates a Puppy named "Buddy" and calls bark() on it.

Expected output:

Yip! I am Buddy
STEP 1 OF 2
    Ctrl + Enter to check

    JAVASCRIPT · OBJECT-ORIENTED PROGRAMMING

    Method Overriding in JavaScript, explained

    What overriding means

    A child class inherits its parent's methods. Overriding is what you do when the child wants to change one of them. If the child defines a method with the same name as the parent's, the child's version is used for objects of the child class. The parent's version is still there for parent objects.

    A puppy is a dog, but it sounds different: "Yip!" instead of "Woof!". Instead of inventing a new method name, you redefine bark() in Puppy. Code that calls bark() doesn't need to know which kind of dog it holds, and the right version runs.

    How to override in JavaScript

    JavaScript needs no keyword. You write the method again in the child class, with the same name:

    class Dog {
        bark() { console.log("Woof!"); }
    }
    
    class Puppy extends Dog {
        bark() { console.log("Yip!"); }
    }
    
    new Dog().bark();     // Woof!
    new Puppy().bark();   // Yip!
    

    The parent doesn't mark anything as overridable, and the child doesn't mark its method as an override. That differs from C#, which needs virtual and override, and from Java, where the optional @Override annotation makes the compiler check the signature. In JavaScript, nothing checks. The method lookup simply finds the child's version first, because it searches the object's class and then climbs the chain of parent classes.

    Calling the parent's version with super

    Sometimes the child wants to extend the parent's behavior instead of replacing it. Inside a method, super.methodName() calls the parent's version:

    class Dog {
        constructor(name) { this.name = name; }
        bark() {
            console.log("Woof! I am " + this.name);
        }
    }
    
    class Puppy extends Dog {
        bark() {
            super.bark();
            console.log("Yip!");
        }
    }
    
    new Puppy("Zed").bark();
    

    This prints:

    Woof! I am Zed
    Yip!
    

    Here this.name is still the puppy's name, because the parent's method runs on the same object.

    Same name, different behavior

    The real payoff is that one call can behave differently depending on the object:

    let animals = [new Dog("Rex"), new Puppy("Buddy")];
    for (let a of animals) {
        a.bark();
    }
    

    The loop is written once, but the first element runs Dog.bark and the second runs Puppy.bark. The next lesson, on polymorphism, builds on this.

    Overriding built-in methods

    Every class also inherits a few methods from JavaScript itself, and you can override those the same way. The best-known is toString(), which JavaScript calls when it needs an object as text. Without an override, String(new Dog("Rex")) gives [object Object]. After adding toString() { return "Dog " + this.name; } to the class, the same call gives Dog Rex, and a subclass can override it again to print Puppy Rex.

    The exercise, step by step

    The starter code gives Dog a bark that prints Woof! I am and the name, and an empty Puppy subclass. A Puppy named "Buddy" calls bark(). Right now that prints the dog's version.

    1. Declare the method. Inside Puppy, write bark() { }, with the same name and no parameters, exactly like the parent's.
    2. Fill in the body. Log "Yip! I am " followed by this.name. The property name was set by Dog's constructor, which a subclass without its own constructor runs automatically.

    The solution in JavaScript

    class Dog {
        constructor(name) { this.name = name; }
        bark() {
            console.log("Woof! I am " + this.name);
        }
    }
    
    class Puppy extends Dog {
        bark() {
            console.log("Yip! I am " + this.name);
        }
    }
    
    let buddy = new Puppy("Buddy");
    buddy.bark();
    

    The output is:

    Yip! I am Buddy
    

    Common mistakes

    • Misspelling the method name. JavaScript is case-sensitive. Writing Bark() or barks() in the child doesn't override anything. It adds a new method, and buddy.bark() keeps printing the parent's text. No error warns you, so when an override seems ignored, compare the two names character by character.
    • Expecting overloading. JavaScript has no overloads. A method is found by name only, so a child's bark(loud) replaces the parent's bark() completely, whatever the parameters.
    • Dropping the parent's work by accident. If the child should still do what the parent does, call super.bark(). Without that call the parent's body doesn't run.
    • Writing a bare name. Use this.name to read the property.
    • Overriding in the wrong class. The new bark goes into Puppy. Changing Dog would change every dog, not only puppies.

    Key takeaways

    • A child class overrides a method by defining one with the same name.
    • JavaScript uses no keyword for it and does not check that the names match.
    • Use super.method() to reuse the parent's version inside the override.
    • Calling the same method on different objects can produce different results.
    Keep going with JavaScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free