Start learning free

LESSON 183 OF 344 · OBJECT-ORIENTED PROGRAMMING

Method Overriding in Python: Replacing Inherited 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:
    def bark(self):
        print("Woof!")
class Puppy(Dog):
    def bark(self):
        print("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

    PYTHON · OBJECT-ORIENTED PROGRAMMING

    Method Overriding in Python, explained

    What overriding means

    A subclass inherits its parent's methods. Overriding is what you do when you want to change one of them. If the child class defines a method with the same name as the parent's, the child's version is used for objects of the child class. A Puppy is a Dog, but it sounds different: it says "Yip!" where a plain dog says "Woof!". Instead of inventing a new method name, you redefine bark() on Puppy.

    class Dog:
        def bark(self):
            print("Woof!")
    
    class Puppy(Dog):
        def bark(self):
            print("Yip!")
    
    Dog().bark()
    Puppy().bark()
    
    Woof!
    Yip!
    

    Code that holds a dog does not need to know which kind it is. It calls bark(), and the right version runs.

    The parent is not changed by this. Dog objects still use the original method, and only Puppy objects get the new one.

    How Python decides

    Python has no keyword for overriding. There is no override, no virtual, and no required decorator. A method is looked up by name, starting at the object's own class and moving up through its parents. The first class that defines the name wins. Since Puppy defines bark, the search stops there and never reaches Dog.bark.

    The flip side is that Python does not check that you really meant to override. If you misspell the name, you simply add a new method and the inherited one stays in charge:

    class Puppy(Dog):
        def Bark(self):
            print("Yip!")
    

    With this class, Puppy().bark() still prints Woof!, because Bark with a capital B is a different name.

    Extending instead of replacing

    Sometimes you want the parent's behavior plus something more. Inside the override, super() reaches the parent's version:

    class Puppy(Dog):
        def bark(self):
            super().bark()
            print("(squeaky)")
    

    Calling bark() on a puppy now prints Woof! followed by (squeaky). This lesson's exercise replaces the behavior fully and does not call super().

    The lesson's exercise

    The starter code has Dog, whose constructor stores a name and whose bark prints "Woof! I am " plus the name. It also opens class Puppy(Dog): with an empty body, and at the bottom creates buddy = Puppy("Buddy") and calls buddy.bark(). The task is to give Puppy its own bark.

    1. Write the header. Inside Puppy, indented, write def bark(self):. The name matches the parent's method exactly, and it takes self like any method.
    2. Write the body. Print "Yip! I am " joined with self.name. The attribute exists because Puppy has no constructor of its own and so uses Dog.__init__.

    A method with only a header is a syntax error, so you cannot run the code between the two steps.

    class Dog:
        def __init__(self, name):
            self.name = name
        def bark(self):
            print("Woof! I am " + self.name)
    
    class Puppy(Dog):
        def bark(self):
            print("Yip! I am " + self.name)
    
    buddy = Puppy("Buddy")
    buddy.bark()
    
    Yip! I am Buddy
    

    Overriding in other languages

    Python's approach is the simplest of the common languages. C# needs virtual in the parent and override in the child. Java treats non-final methods as overridable, with an optional @Override annotation that makes the compiler verify the signature. C++ needs virtual in the parent. In Python and JavaScript, you just define the method again.

    Common mistakes

    • A different name. Any difference in spelling or capitalization creates a new method instead of an override.
    • A different parameter list. Python allows an override with other parameters, but callers that use the parent's form then break. If Puppy.bark required an extra argument, a plain bark() call would raise a TypeError. Keep the parameters compatible.
    • Forgetting self. The override is a method like any other and needs self first.
    • Repeating the parent's code. If the override needs most of what the parent does, call super().bark() rather than copying the lines.

    Key takeaways

    • Overriding means defining a method with the parent's name in the child class. No keyword is needed.
    • Python searches the object's class first, so the child's version wins.
    • super() reaches the parent's version when you want to extend it.
    • Misspelling the name silently creates a new method.
    Keep going with PythonAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free