Multiple inheritance and mixin classes

13.5 Multiple inheritance and mixin classes

Learning objectives

By the end of this section you should be able to

  • Construct a class that inherits from multiple superclasses.
  • Identify the diamond problem within multiple inheritance.
  • Construct a mixin class to add functionality to a subclass.

Multiple inheritance basics

Multiple inheritance is a type of inheritance in which one class inherits from multiple classes. A class inherited from multiple classes has all superclasses listed in the class definition inheritance list. Ex: class SubClass(SuperClass_1, SuperClass_2).

Checkpoint

Multiple inheritance organization

Concepts in Practice

Implementing multiple inheritance

Consider the program:

    class A:
      def __init__(self, a_attr=2):
        self.a_attr = a_attr

    class B:
      def __init__(self, b_attr=4):
        self.b_attr = b_attr

    class C(A, B):
      def __init__(self, a_attr=5, b_attr=10, c_attr=20):
        A.__init__(self, a_attr)
        B.__init__(self, b_attr)
        self.c_attr = c_attr

    b_inst = B(2)
    c_inst = C(1, 2)
1.
What is the value of c_inst.a_attr?
  1. 1
  2. 5
  3. Error
2.
What is the value of c_inst.c_attr?
  1. 2
  2. 20
  3. Error
3.
What is the value of b_inst.a_attr?
  1. 2
  2. 4
  3. Error

The diamond problem and mixin classes

Multiple inheritance should be implemented with care. The diamond problem occurs when a class inherits from multiple classes that share a common superclass. Ex: Dessert and BakedGood both inherit from Food, and ApplePie inherits from Dessert and BakedGood.

A conceptual diagram illustrating a classification hierarchy. 'ApplePie' is shown as a subtype of both 'Dessert' and 'BakedGood', which in turn are both subtypes of 'Food'.
Figure 13.2 The diamond problem. If both
Dessert
and
BakedGood
override a
Food
method, the overridden
Food
method that
ApplePie
inherits is ambiguous. Thus, diamond shaped inheritance should be avoided.

Mixin classes promote modularity and can remove the diamond problem. A mixin class:

  • Has no superclass
  • Has attributes and methods to be added to a subclass
  • Isn't instantiated (Ex: Given MyMixin class, my_inst = MyMixin() should never be used.)

Mixin classes are used in multiple inheritance to add functionality to a subclass without adding inheritance concerns.

Concepts in Practice

Creating a mixin class

The following code isn't correct, as not all plants are carnivorous. Follow the programmer through the programmer's edits to improve the program. Note: Rose, Pitcher, and VenusFlyTrap represent plants that all photosynthesize. Pitcher and VenusFlyTrap represent plants that are also carnivorous and can eat.

A pass statement is used in Python to indicate that code is to be written later and prevents certain errors that would result if no code was written or a comment was used instead.

    class Plant:
      def photosynth(self):
        print("Photosynthesizing")

      def eat(self):
        print("Eating")

    class Rose(Plant):
      pass

    class Pitcher(Plant):
      pass
    
    class VenusFlyTrap(Plant):
      pass
4.
Which edit is appropriate?
  1. Move eat() to a different class.
  2. Remove Plant as a superclass.
5.
The programmer edits the code as follows. How can the program be improved?
class Plant:
  def photosynth(self):
    print("Photosynthesizing")

class Rose(Plant):
  pass

class Pitcher(Plant):
  def eat(self):
    print("Eating")

class VenusFlyTrap(Plant)
  def eat(self):
    print("Eating")
  1. Move photosynth() into Rose.
  2. Remove redundancy of eat().
6.
The programmer edits the code to create a mixin class containing eat(). Which class name, replacing X, is most appropriate for the mixin?
class Plant:
  def photosynth(self):
    print("Photosynthesizing")

class X:
  def eat(self):
    print("Eating")

class Rose(Plant):
  pass

class Pitcher(Plant, X):
  pass

class VenusFlyTrap(Plant, X)
  pass
  1. CarnivClass
  2. CarnivMixin

Try It

Fixing the diamond problem with a mixin class

The program below represents multiple inheritance and has the diamond problem. Edit the program to use a mixin class, OnlineMixin. OnlineMixin:

  • Replaces OnlineShop.
  • Is a superclass of FoodFast.
  • Has one method, process_online(), which prints "Connecting to server" and is called by FoodFast's process_order().

The output should match:

    Processing meal order
    Connecting to server
    Enjoy your FoodFast order