-1

I'm a bit confused about how method overriding works in Python.

Let's say I have a base class with a method, and I override that method in a subclass. When I call the method from the subclass, the overridden version runs which makes sense. But when I call it on the base class instance, it still uses the original method. Why is that?

Example:

class Animal:
    def speak(self):
        return "Animal speaks"

class Dog(Animal):
    def speak(self):
        return "Dog barks"

a = Animal()
d = Dog()

print(a.speak())
print(d.speak())

Output:

Animal speaks 
Dog barks

I get that the subclass has its own version of the method, but I'm trying to understand why the base class isn't somehow affected. Is it because each class handles its own method separately? Or is there something deeper going on in how Python handles method resolution?

5
  • 3
    What would you expect to happen if there were 100 subclasses that each printed something different, and then you called speak on the parent? Subclassing affecting the parent would be a mess that would lead to fragile code. Commented Jul 19 at 18:24
  • 3
    "why the base class isn’t somehow affected." - if it were, then it would defeat the whole purpose of inheritance. What you override in a subclass is meant to be available in the subclass only. Commented Jul 19 at 18:24
  • 5
    This isn't a Python behaviour, it's how Object Oriented Programming is designed to work. A sub-class is a new class, using its parent as a template, which can then make changes to itself (not its parent). Commented Jul 19 at 18:52
  • 1
    Hi and welcome to StackOverflow. Thanks for asking a clear question and providing a minimal reproducible example, thats good for a first question. Documentation is not always easy to understand, so next time, please provide what documentation you found and what confuse you. Commented Jul 19 at 19:22
  • if u create a cat class which inherits from animal class, then you call the methods and it returns dog barks, does it make sense? Commented Oct 29 at 7:36

1 Answer 1

4

This behavior is not specific to Python, but this answer will focus on Python explanation.

The dependency goes from parent to children classes.

You can see inheritance as creating a new dict from a previous one.

foo = {
    "speak": 1,
    "run": 2,
}

bar = foo | {"speak": 3}  # we merge/override new values into the newly formed dict

print(foo)  # {'speak': 1, 'run': 2}
print(bar)  # {'speak': 3, 'run': 2}

To give you an example close to your case:

Animal = {"speak": lambda: "Animal speaks"}
# Merge with already existing values is similar to subclass overriding
Dog = Animal | {"speak": lambda: "Dog barks"}

# Your can see .copy() as the object instanciation in this demonstration
some_animal = Animal.copy()
some_dog = Dog.copy()

print(some_animal["speak"]())  # Animal speaks
print(some_dog["speak"]())  # Dog barks

And that would be pretty close to reality. Under the hood, a class is only a glorified dict that you copy when you create an instance (and add new values in the init). In fact, you can find this dict in the dunder attribute __dict__:

class Animal:
    def speak(self):
        return "Animal speaks"

print(Animal.__dict__)
# {..., 'speak': <function Animal.speak at 0x...>, ...}

If that helps: https://docs.python.org/3/tutorial/classes.html#inheritance


You need to remember that in Python, names are only references to a memory value. Those references are bound to a namespace. The speak reference doesn't exists, only Animal.speak and Dog.speak. By defining an override in Dog, you create a new function named "speak" in memory, and make the Dog.speak reference point to that function. Doing so, you changed one and only one reference, Dog.speak, not Animal.speak who keep referencing the first speak function created.

memory reprezentation of OP code with another method

You can play with this code here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.