Inheritance is an important way of object-oriented programming because, by inheritance, subclasses can extend the functionality of the parent class.
Recall the Animal
class-level design, assuming we want to implement the following 4 kinds of animals:
- Dog-Dogs;
- Bat-bat;
- Parrot-Parrot;
- Ostrich-Ostrich.
If we classify mammals and birds, we can design a hierarchy of such classes:
But if we classify "can run" and "Can fly", we should design the hierarchy of such classes:
If we want to include both of the above categories, we have to design more layers:
- Mammals: Mammals that can run, mammals that can fly;
- Birds: Birds that can run, birds that can fly.
In this way, the hierarchy of classes is complex:
If you want to increase the "pet" and "non-pet", so that the number of classes will increase exponentially, it is obvious that this design is not possible.
The correct approach is to use multiple inheritance. First, the main class levels are still designed according to mammals and birds:
class Animal(object): pass# 大类:class Mammal(Animal): passclass Bird(Animal): pass# 各种动物:class Dog(Mammal): passclass Bat(Mammal): passclass Parrot(Bird): passclass Ostrich(Bird): pass
Now, we're going to add Runnable
and Flyable
function to the animals, just need to define Runnable
the good and Flyable
the class first:
class Runnable(object): def run(self): print(‘Running...‘)class Flyable(object): def fly(self): print(‘Flying...‘)
For Runnable
animals that require functionality, they inherit one more Runnable
, for example Dog
:
class Dog(Mammal, Runnable): pass
For Flyable
animals that require functionality, they inherit one more Flyable
, for example Bat
:
class Bat(Mammal, Flyable): pass
With multiple inheritance, a subclass can get all the functionality of multiple parent classes at the same time.
Mixin
When you design an inheritance relationship for a class, the main line is usually a single inheritance, for example, Ostrich
inheriting from Bird
. However, if you need to "mix in" additional functionality, it can be achieved through multiple inheritance, for example, by inheriting Ostrich
from Bird
the inheritance Runnable
. This design is often called mixin.
In order to better see the inheritance relationship, we put Runnable
and Flyable
change to RunnableMixin
and FlyableMixin
. Similarly, you can define predators CarnivorousMixin
and plant animals HerbivoresMixin
to have several mixin at the same time:
class Dog(Mammal, RunnableMixin, CarnivorousMixin): pass
The purpose of mixin is to add multiple functions to a class, so that when designing a class, we prioritize the ability to combine multiple mixin with multiple inheritance, rather than designing complex, hierarchical inheritance relationships.
Many of the libraries that Python comes with also use mixin. For example, Python comes with both TCPServer
types of UDPServer
network services, and to serve multiple users at the same time must use a multi-process or multithreaded model, both of which are provided by the model ForkingMixin
ThreadingMixin
. By combining, we can create the right services.
For example, a TCP service that writes a multi-process pattern is defined as follows:
class MyTCPServer(TCPServer, ForkingMixin): pass
Write a multithreaded mode of the UDP service, defined as follows:
class MyUDPServer(UDPServer, ThreadingMixin): pass
If you're going to make a more advanced model of the process, you can write a CoroutineMixin
:
class MyTCPServer(TCPServer, CoroutineMixin): pass
In this way, we do not need a complex and large inheritance chain, as long as you choose to combine the functions of different classes, you can quickly construct the desired subclass.
Summary
Because Python allows multiple inheritance, mixin is a common design.
Only single-inherited languages, such as Java, are allowed to use the mixin design.
Python Multiple inheritance