Subclassing in Python looks like Java's extends, but method lookup is governed
by an explicit, inspectable list called the method resolution order (MRO). Calling
obj.method() is just "walk the MRO until a class defines it." super() means
"continue from here in that same list."
class SavingsAccount(Account) declares that a savings account is an account: it gets
every attribute and method of Account for free, and may add new ones or override
existing ones. Every class also implicitly inherits from object, the root of all Python types —
which is where __init__, __str__, and friends ultimately come from.
When you call a method, Python doesn't guess — it consults the class's MRO, a definite ordering of the
class and its ancestors, and uses the first class in that list that defines the method. For a simple
chain the MRO is exactly bottom-to-top: [SavingsAccount, Account, object]. Toggle whether the
subclass overrides describe(), pick a method to call, and watch the search walk the chain:
super(): extend, don't replaceOverriding usually means "do what the parent did, and then a bit more" — not "throw the parent's
work away." super() gives you the parent's version (precisely: the next class in the
MRO). The canonical use is in __init__, so the subclass sets up its own fields and lets
the base class set up the shared ones:
Without that super().__init__(...), the parent's setup never runs and self.owner
wouldn't exist. The same pattern works for any overridden method: call super().describe() to
reuse the parent's behaviour and append to it.
Because the MRO is explicit, you can print it: SavingsAccount.__mro__ (or
.mro()) lists exactly the classes Python will search, in order. For multiple inheritance Python
computes the order with an algorithm called C3 linearization that keeps it consistent — but if you
find yourself reasoning hard about diamond hierarchies, that's usually a sign to prefer composition
(hold an object as an attribute) over deep inheritance. Subclass only for a genuine is-a
relationship.
class Sub(Base) inherits everything and may override.
obj.method() searches the MRO — [Sub, …, object] — and uses the first match.
super() calls the next class in that list, letting you extend rather than replace
(especially __init__). Inspect with __mro__; favour composition over tall trees.Builds on classes & the namespace model. Step through
a super() call in Python Tutor.