8 The Rules (and Exceptions) of Inheritance

This chapter covers:

  • Using inheritance and composition together to model systems
  • Using Python built-ins to inspect object types
  • Making interfaces more strict with abstract base classes

If you’ve written your own classes or used a class-based framework in Python, you’ve almost certainly encountered inheritance. Classes can inherit from other classes, ending up with their parent class' data and behavior. In this chapter you’ll learn the details of inheritance in Python, where it works well, and where it should be avoided.

8.1  The inheritance of programming past

Inheritance was conceived of in the early days of computer programming, but although it’s existed for a long time, folks still have spirited debates about when and how it should be used. For much of the history of object-oriented programming, inheritance was the name of the game. Many applications sought to model the real world as a carefully-curated hierarchy of objects, in the hopes that it would lead to some kind of obvious, neat structure. This paradigm was so embedded into object-oriented programming practices that the two concepts—object-oriented programming and inheritance—were nearly inseparable.

8.1.1  The silver bullet

Though inheritance is the right tool to reach for sometimes, it has been used on occasion as the hammer for every nail—the elusive "silver bullet." Much like a silver bullet, however, a paradigm that meets every need is a work of fiction.

8.1.2  The challenges of hierarchies

8.2  The inheritance of programming present

8.2.1  What is inheritance for, really?

8.2.2  Substitutability

8.2.3  The ideal use case for inheritance

8.3  Inheritance in Python

8.3.1  Type inspection

8.3.2  Superclass access

8.3.3  Multiple inheritance and method resolution order

8.3.4  Abstract base classes

8.4  Inheritance and composition in Bark

8.4.1  Refactoring to use an abstract base class

8.4.2  A final check on your inheritance work

8.5  Summary