Wiki
Core13 min read

Inheritance and polymorphism

Reuse a base class, override the parts that differ, and let method lookup at call time pick the right behaviour.

Duplication is the enemy of change. If two classes share most of their behaviour and differ in one method, inheritance lets you write the common part once in a base class and override only what changes. The payoff is not the typing saved; it is that one call site can work with objects of many different classes.

Same message, different response

Polymorphism means the caller writes shape.area() without caring which concrete type shape is. Python looks up area on the object's class at call time and runs whichever definition it finds first. The object decides, not the caller.

The panel below builds a diamond hierarchy, D(B, C) with both bases deriving from A, and shows the method resolution order that decides which who() runs.

Choose which classes define who(), then call it on a D and follow the lookup

who() defined in

D.who()

MRO of D (left to right)

DBCAruns

who() resolved to A.who

first class in the MRO that defines the method

B and C both derive from A, so the linearization has to put A after both — never before a subclass. That single constraint is what stops a shared base from quietly winning over an override.

Polymorphism is just this lookup happening at call time: the same obj.who() runs different code depending on the object's class, and the MRO decides which one when inheritance branches.

Overriding and super()

A subclass inherits every method of its base. To replace one, define a method with the same name; to extend it, call the base version with super():

class Animal:
    def __init__(self, name):
        self.name = name
 
    def speak(self):
        return "..."
 
class Dog(Animal):
    def speak(self):                 # overrides Animal.speak
        return "Woof"

Dog("Rex").speak() returns "Woof"; Animal("x").speak() still returns "...". The base class is untouched, and existing callers keep working.

The method resolution order

With single inheritance the lookup is a straight line: class, then base, then object. With multiple inheritance, super() and attribute lookup follow the MRO, computed by the C3 linearization. The ordering guarantees a subclass comes before its bases and a base appears before its own superclass — which is why the diamond above always puts A after both B and C.

Diamonds need cooperative __init__

If two bases both define __init__ and neither calls super().__init__(...), the second one is silently skipped. Each __init__ should call super().__init__(**kwargs) so the chain reaches every class in the MRO exactly once. Prefer composition when the hierarchy stops being obvious.

Duck typing

Python does not require a shared base class for polymorphism. It only requires that the object answers the message:

If it walks like a duck and quacks like a duck, treat it as a duck.

Any object with an area() method works where an area is expected, regardless of its ancestry. Inheritance is a tool for reuse; polymorphism comes from the protocol, not the class tree.

Illustrative vs real

The explorer pips every class into a single method so the resolution path is readable. Real hierarchies mix abstract base classes (abc.ABC), mixins, properties and dunder protocols such as __iter__. C3 still computes the MRO, and super() still follows it, no matter how deep the tree.

Check yourself

Eduspheria wiki · Programming & Data Structures, Objects and I/O

0 / 5 answered

  1. 1What does super() return?
    Multiple choice
  2. 2Python requires a common base class for polymorphism.
    True / false
  3. 3What is the ordering of classes that decides which method wins called?
    Short answer
  4. 4In the diamond D(B, C), both B and C inherit from A. If only B defines who(), which runs for an object of D?
    Multiple choice
  5. 5For a class hierarchy with MRO [D, B, C, A, object], what is the 1-based position of A?
    Numeric answer

From the assignment paper

Modeled on NITJ AI-503, Assignment/Quiz

0 / 5 answered

  1. 1A class is derived from another class that was itself already derived from a third. What is this technique called?
    Multiple choice
  2. 2Inheritance is usually described as building a solution with which approach?
    Multiple choice
  3. 3Which kind of class is not meant to be instantiated directly?
    Multiple choice
  4. 4Which line correctly defines a subclass Derived that inherits from Base?
    Multiple choice
  5. 5A class People defines an initialiser that stores the name. Two objects are created, person1 with Sally and person2 with Louise, and then person1.namePrint() runs. What is printed?
    Multiple choice

Where next: exceptions — what to do when an operation cannot do what was asked.