Inheritance and super()
Imagine you already have an "animal" blueprint: a name, a sound and the ability to speak. Now you need a cat blueprint. There is no reason to draw everything again. You can take a copy of the old blueprint and write in the margin: "everything as for an animal, but it speaks differently".
Without that option, code would have to be copied. A cat and a dog, like any animal, have a name and a sound, and they speak in almost the same way. If you copy __init__ and the methods into each class, the same fix will later have to be made in several places. A class can take everything from another class and change only what differs:
class Animal:
def __init__(self, name):
self.name, self.sound = name, "..."
def speak(self):
return f"{self.name} says {self.sound}"
class Cat(Animal):
def speak(self):
return f"{self.name} purrs"
print(Animal("Ox").speak()) # Ox says ...
print(Cat("Tom").speak()) # Tom purrsInheritance
The line class Cat(Animal) means inheritance: Cat is the child class, and Animal is the parent class. The child class gets all the methods and attributes of the parent class.
Let's take apart what happens on the call Cat("Tom"):
Cathas no__init__of its own, so Python takes the__init__ofAnimal.- That
__init__creates the cat's attributesnameandsound. Cat("Tom").speak()calls thespeakofCatand returns"Tom purrs".
Overriding a method
Python looks for a method first in the instance's class, then in the parent class. The speak method of Cat overrides the parent's method: for a cat, that one is found.
So one and the same call works with objects of different classes, and each object runs its own method:
pets = [Animal("Ox"), Cat("Tom")]
print([pet.speak() for pet in pets]) # ['Ox says ...', 'Tom purrs']
print(isinstance(pets[1], Animal), isinstance(pets[0], Cat)) # True FalseAn instance of a child class also counts as an instance of the parent class: isinstance(pets[1], Animal) gives True. The reverse is false: Animal("Ox") is not a Cat.
The code that calls pet.speak() does not check the pet's class: a new class of animal needs only its own speak method. In interviews this is called polymorphism: one call, with behavior that depends on the object's class.
Calling super()
If a child class needs its own __init__, that method replaces the parent's __init__ entirely: Python itself calls only the child's __init__. For the parent's code to run as well, it is called through super():
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
self.sound = "woof"
rex = Dog("Rex", "husky")
print(rex.speak(), rex.breed) # Rex says woof huskyLet's go through the __init__ of Dog line by line:
super().__init__(name)runs the__init__ofAnimalfor the sameself:rexgetsnameand asoundholding"...".self.breed = breedadds the breed.self.sound = "woof"replaces the sound.
The last assignment wins: if sound is set before the super() call, the parent's __init__ writes "..." into it again. Other parent methods are called through super() too: super().speak() inside a Dog method returns the text of the Animal method.
This is where the blueprint-copy analogy stops working. A child class does not copy the parent's methods into itself. It keeps a link to the parent, and Python looks for a method along the chain each time: first in Dog, then in Animal.
Common mistake
A child's __init__ forgets to call super().__init__():
class Bird(Animal):
def __init__(self, name):
self.sound = "tweet" # ✗
print(Bird("Kiwi").speak())AttributeError: 'Bird' object has no attribute 'name'The child's own __init__ replaced the parent's, and the line that sets self.name never ran. If the parent has an __init__ of its own, make super().__init__(name) the first line of the child's __init__.
Key points
class Cat(Animal)is inheritance: the child class gets the parent's methods and attributes.- A method with the same name in the child class overrides the parent's method.
- An
__init__of its own replaces the parent's entirely, so the parent's code is called throughsuper().__init__(...). - An instance of a child class is also an instance of the parent class:
isinstancegivesTrue.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.