Inheritance & super()
- Extend a base class with a subclass
- Override methods while preserving behavior with
super() - Understand the
is-arelationship inheritance encodes - Decide when composition beats inheritance
Django's class-based views, DRF serializers, and SQLAlchemy's declarative base all lean on multiple inheritance and cooperative super() calls. Understanding the C3 linearization MRO is what separates engineers who can debug a diamond-shaped mixin stack from those who cargo-cult super().__init__() and pray.
- Forgetting
**kwargsin cooperative__init__— every mixin in a chain must forward unknown args or the MRO breaks silently. - Calling
Parent.__init__(self)instead ofsuper().__init__()— this skips siblings in the MRO and defeats mixin composition. - Assuming left-to-right resolution — read
Cls.__mro__before debugging; C3 is subtler than it looks.
A child class inherits every attribute and method of its parent. Override what you want to change.
super()
Calls the parent's version of a method. Use it inside __init__ to delegate setup, and inside overridden methods to extend behavior.
When to use it
- "B is a kind of A" relationships —
Puppy is a Dog - Sharing logic across closely-related types
When NOT to
- Just to share helper code → use composition or a module function
- More than 2–3 levels deep → usually a smell
Try it
- Add a
Catclass with its ownspeak(). - Build a
Petmixin that addsownerto any Animal subclass.
3 graded exercises
Write the code, click Check. We’ll tell you exactly what to fix.
- Exercise 1
Given the parent
Animalclass (already defined below), create a subclassDogthat overridesspeak(self)to return"Woof!". Then printDog("Rex").speak()— expected:Woof!. - Exercise 2
Extend
Dogfurther into a subclassPuppywhose__init__(self, name, breed)usessuper().__init__(name)and storesbreed. Itsspeak(self)returns"Yip! Woof!"(usessuper().speak()). PrintPuppy("Toby", "Lab").speak(). - Exercise 3
Given a
Shapeclass witharea(self)returning0, defineCircle(radius)andSquare(side)— both inherit fromShapeand overridearea. PrintCircle(5).area()(~78.54) andSquare(4).area()(16). Usemath.pifor the circle.