28 · Inheritance and super()
Build class hierarchies with class Child(Parent), call parent code with super(), understand the MRO, and learn when to prefer composition over deep inheritance.
One idea, one try. At your own pace.
LEARN BY DOINGPut your intuition to work3 steps
28 · Inheritance and super()
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.`class Child(Parent):` means "Child **is a** Parent, plus extra". The child inherits every method and attribute of the parent. `super().__init__(...)` delegates to the parent's `__init__` so you don't duplicate setup code. Python resolves method lookup through the **Method Resolution Order (MRO)** — a left-to-right, depth-first search that handles multiple inheritance correctly.
Without this:
Without inheritance you'd copy `.fit()` and `.predict()` into every estimator class. The entire sklearn taxonomy — `BaseEstimator`, `ClassifierMixin`, `RegressorMixin` — relies on inheritance to share dozens of utility methods across hundreds of models.
Inheritance lets a class reuse and extend the behaviour of another. The parent (base) class holds the shared implementation; each child (derived) class inherits it and can override methods — replacing the parent's version by defining a method with the same name.
super() gives you a proxy to the parent class. Calling super().__init__(...) inside a child's __init__ runs the parent's initialiser so you don't have to duplicate the attribute setup. You can similarly call super().method_name(...) to run the parent's version of any overridden method — useful when you want to extend rather than replace behaviour.
Multiple inheritance (class D(B, C):) is allowed in Python. When the same method name appears in multiple parents, Python uses the C3 linearisation algorithm to build a deterministic MRO (Method Resolution Order). ClassName.__mro__ or help(ClassName) shows you the full resolution chain — worth checking whenever you see surprising method binding. The general advice: favour composition (a model HAS-A scaler) over deep inheritance hierarchies (a model IS-A scaler IS-A estimator IS-A ...) — deep hierarchies become hard to understand and debug.
Python (in browser)
`super().__init__(name)` and `super().fit(X, y)` are the two most common uses of `super()`. Without `super().__init__()`, the child's `__init__` would have to duplicate all the parent's attribute setup — and any future changes to the parent's `__init__` would need to be mirrored manually.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
The MRO for `D` is `[D, B, C, A, object]`. When `B.hello` calls `super().hello()`, Python looks up the MRO from `B`'s position — the next class is `C`, not `A`. This is why the diamond outputs `"B -> C -> A"` and not `"B -> A"`. Understanding MRO prevents mysterious "wrong method was called" bugs in multi-inherit hierarchies.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Every PyTorch model inherits from `nn.Module`. The `super().__init__()` call is mandatory — it wires up the internal parameter registry that tracks gradients. You override `forward()` (the parent declares it but expects you to replace it) and call the model as a function: `output = model(x)` invokes `__call__`, which wraps `forward`.
What does `super().__init__()` do inside a child class's `__init__`?
- `class Child(Parent):` inherits everything from `Parent`. Override a method by redefining it; call the parent's version with `super().method_name(...)`.
- `super().__init__(...)` runs the parent's `__init__` on the current instance — always call it first in child `__init__` unless you have a deliberate reason not to.
- Python's MRO (`ClassName.__mro__`) defines method resolution order for multiple inheritance. Prefer composition over deep inheritance hierarchies in production ML code.
Every PyTorch model inherits from `nn.Module` — `super().__init__()` is the first line of every `__init__`. Sklearn uses `BaseEstimator` + mixin classes (`ClassifierMixin`, `RegressorMixin`) to inject `get_params`, `set_params`, `score`, and other utilities via multiple inheritance. LightGBM and XGBoost wrap their C++ models in Python classes that inherit from `BaseEstimator` so they slot into sklearn pipelines without modification.
If you remove it: Without inheritance, every model would re-implement `get_params`, `set_params`, `clone`, and `score` from scratch — thousands of lines of duplicated utility code across the sklearn ecosystem alone.