liveBook · Manning

Inheritance

As explained in Python Workout: 50 ten-minute exercises

Inheritance is an object-oriented technique in which a class derives functionality from an existing parent class and can add or modify that functionality.

When several classes share most of their behavior, put the general behavior in a parent class and derive more specific subclasses. An Employee can extend Person with an ID, department, and salary; Car, Truck, and Bicycle can extend Vehicle. The subclass keeps the parent’s interface while adding or modifying functionality, reducing duplicated code. section 9.15

Inheritance expresses an “is-a” relationship: an employee is a person, and a car is a vehicle. A Bowl containing Scoop objects expresses “has-a,” which is composition instead. Choosing between these relationships prevents every pair of related classes from becoming an inheritance hierarchy. section 9.7

Python resolves inherited behavior through a lookup process:

  • Search the instance first, then its class, then the class’s parents, continuing to object if necessary. section 9.10
  • Use a subclass method when specialized behavior should replace the parent method; otherwise, inherit the existing implementation unchanged. section 9.10
  • Call super().__init__ when a subclass adds initialization but should retain the parent’s setup. section 9.15 section 9.27
  • Reference self.max_scoops rather than Bowl.max_scoops when one inherited method must use different class-level values for different subclasses. section 9.17

A subclass reuses and extends a parent

class Foo(): def __init__(self, x): self.x = x def x2(self): return self.x * 2 class Bar(Foo): def x3(self): return self.x * 3 b = Bar(10) print(b.x2()) # inherited: 20 print(b.x3()) # subclass behavior: 30 Bar receives Foo’s initializer and x2 method without redefining them, then adds x3. The same pattern supports a BigBowl that changes only the scoop limit, or a FlexibleDict that changes only key retrieval. section 9.10 section 9.22 section 9.17

Inheritance is useful but should not be automatic. It can reduce code size and improve maintenance when subclasses genuinely specialize a parent. It can also produce oversized, difficult hierarchies. Extending built-in types is possible, but behavior should remain unambiguous; FlexibleDict is useful as practice while its guessing behavior is discouraged. section 9.20 section 9.22

class Foo():
    def __init__(self, x):
        self.x = x
    def x2(self):
        return self.x * 2
 

class Bar(Foo):
    def x3(self):
        return self.x * 3
 

b = Bar(10)
 
print(b.x2())     #1
print(b.x3())     #2

Runnable Foo and Bar code makes inherited initialization, reused methods, and subclass-specific behavior visible in a minimal example. section 9.10

How Python Workout: 50 ten-minute exercises covers it

How deep it goes
Traces attribute lookup through instances, classes, parents, and object, then applies super and subclass-specific class attributes.
Examples
Demonstrates Person and Employee, Foo and Bar, Bowl and BigBowl, FlexibleDict, and animal class hierarchies.
What it assumes
Assumes familiarity with Python classes, methods, attributes, and object construction while teaching inheritance lookup through concrete examples.
What you can do after
Build it from scratch by defining parent and child classes, reusing methods, overriding behavior, and delegating initialization with super.
How it connects
Connects inheritance with classes, methods, attributes, super, built-in types, composition, and the DRY principle.

Also explained in

Compare how 19 books explain inheritance →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Workout: 50 ten-minute exercises. The section links point to the parts of the book it draws on.