Challenge 3: Composition Over Multiple Inheritance — Possible Solution ==================================================================== class Flyer: def move(self): return "flying" class Swimmer: def move(self): return "swimming" class Duck: def __init__(self): self._flyer = Flyer() self._swimmer = Swimmer() def fly(self): return self._flyer.move() def swim(self): return self._swimmer.move() d = Duck() print(d.fly()) print(d.swim()) Output: flying swimming WHY THIS WORKS AS AN ANSWER ------------------------------ Rather than class Duck(Flyer, Swimmer): — this chapter's own multiple- inheritance example — this version makes Duck hold a Flyer instance and a Swimmer instance as its own attributes (self._flyer, self._swimmer), set up in __init__ exactly like any ordinary instance attribute from Course 2, Chapter 1. This is composition: "has-a" (Duck has a Flyer) instead of "is-a" (Duck is a Flyer). fly() and swim() are Duck's own methods, each DELEGATING to the matching component's move() method rather than inheriting move() directly. This sidesteps the exact ambiguity the chapter's original example ran into: because Duck no longer inherits move() from two different parents at once, there's no MRO decision to make at all — d.fly() unambiguously calls Flyer's move(), and d.swim() unambiguously calls Swimmer's move(), with the method names themselves (fly/swim) making the intent explicit rather than relying on inheritance order to disambiguate a single shared move() name. This is precisely the trade-off the chapter's warn-box describes: composition trades away automatic inherited behavior for explicit, easy-to-trace delegation — reading Duck's own three lines tells you exactly where fly() and swim() each go, with no need to consult an MRO to understand the class's behavior.