Step 1 of 7 · Reading · ~3 min
Learn
Object-Oriented Programming
Inheritance and Polymorphism
You will predict which method runs when classes are combined, chain behaviour and constructor arguments through mixins, and make a base class refuse to be built until subclasses finish it. In Python in Practice, except ConfigError caught a family of exceptions; here you build hierarchies of behaviour.
Extending with super()
An override that calls super().method() extends the inherited behaviour; one that does not replaces it. __init__ works the same way: hand the base its arguments and keep the extra one yourself.
The method resolution order
Python finds a method along a fixed list, the method resolution order (MRO). Its rule (C3 linearisation): a class comes before its bases, and bases keep the order you listed. Read it from __mro__. super() means "the next class after this one in the MRO of the object", not "my parent":
Mixins and the cooperative chain
A mixin is a small class that adds one behaviour and is listed before the main class. It is cooperative when its methods call super(), so the next class still runs. A mixin with its own constructor argument takes it by keyword and forwards everything else:
The first base runs outermost, so swapping bases changes the answer. Raw skipped super(), cutting the chain silently: Unit.show never ran.
Abstract base classes
Subclassing abc.ABC marks a base that must be finished. The @ line above a def is a decorator (copy it exactly; decorators get their own lesson) and the ... body is a do-nothing placeholder. A subclass that leaves the method unfilled cannot be built:
A plain base whose method does raise NotImplementedError builds fine and fails only when someone calls it. Catch TypeError and print fixed words; its message text changes between Python versions.
Polymorphism and substitutability
Polymorphism means calling p.parse(text) and letting the object pick the code; a chain of isinstance checks needs an edit for every new class. isinstance(x, K) is True when x is a K or a subclass instance: isinstance(Duck(), Swimmer) is True, isinstance(Walker(), Duck) is False. A subclass should work wherever its base does, and a class that only uses another is better off holding it in an attribute (has-a) than inheriting (is-a).
Common mistakes
- Listing a mixin after the class it modifies, as in
class X(Main, Mixin).Main.methodis found first and, if it never callssuper(), the mixin is skipped silently. - A mixin
__init__that does not forward*args, **kwargs. The base never receives its arguments and construction raisesTypeError.
Your exercise
Finish a payroll hierarchy: an abstract Employee, a Manager with a bonus, and a tax mixin with its own rate. The likeliest mistake is listing the bases the wrong way round, which silently skips the tax; print __mro__ to check.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…