继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。

回忆一下Animal类层次的设计,假设我们要实现以下4种动物:

  • Dog - 狗狗;
  • Bat - 蝙蝠;
  • Parrot - 鹦鹉;
  • Ostrich - 鸵鸟。

如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次:

但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次:

如果要把上面的两种分类都包含进来,我们就得设计更多的层次:

  • 哺乳类:能跑的哺乳类,能飞的哺乳类;
  • 鸟类:能跑的鸟类,能飞的鸟类。

这么一来,类的层次就复杂了:

如果要再增加“宠物类”和“非宠物类”,这么搞下去,类的数量会呈指数增长,很明显这样设计是不行的。

正确的做法是采用多重继承。首先,主要的类层次仍按照哺乳类和鸟类设计:

class Animal(object):
pass # 大类:
class Mammal(Animal):
pass class Bird(Animal):
pass # 各种动物:
class Dog(Mammal):
pass class Bat(Mammal):
pass class Parrot(Bird):
pass class Ostrich(Bird):
pass

现在,我们要给动物再加上RunnableFlyable的功能,只需要先定义好RunnableFlyable的类:

class Runnable(object):
def run(self):
print('Running...') class Flyable(object):
def fly(self):
print('Flying...')

对于需要Runnable功能的动物,就多继承一个Runnable,例如Dog

class Dog(Mammal, Runnable):
pass

对于需要Flyable功能的动物,就多继承一个Flyable,例如Bat

class Bat(Mammal, Flyable):
pass

通过多重继承,一个子类就可以同时获得多个父类的所有功能。

MixIn

在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为MixIn。

为了更好地看出继承关系,我们把RunnableFlyable改为RunnableMixInFlyableMixIn。类似的,你还可以定义出肉食动物CarnivorousMixIn和植食动物HerbivoresMixIn,让某个动物同时拥有好几个MixIn:

class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
pass

MixIn的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系。

Python自带的很多库也使用了MixIn。举个例子,Python自带了TCPServerUDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixInThreadingMixIn提供。通过组合,我们就可以创造出合适的服务来。

比如,编写一个多进程模式的TCP服务,定义如下:

class MyTCPServer(TCPServer, ForkingMixIn):
pass

编写一个多线程模式的UDP服务,定义如下:

class MyUDPServer(UDPServer, ThreadingMixIn):
pass

如果你打算搞一个更先进的协程模型,可以编写一个CoroutineMixIn

class MyTCPServer(TCPServer, CoroutineMixIn):
pass

这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

小结

由于Python允许使用多重继承,因此,MixIn就是一种常见的设计。

只允许单一继承的语言(如Java)不能使用MixIn的设计。

python3-多重继承的更多相关文章

  1. Python3多重继承排序原理(C3算法)

    参考:https://www.jianshu.com/p/c9a0b055947b https://xubiubiu.com/2019/06/10/python-%E6%96%B9%E6%B3%95% ...

  2. Python3之多重继承

    继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. Animal类层次的设计,假设我们要实现以下4中动物 Dog-狗狗 Bat-蝙蝠 Parrot-鹦鹉 Ostrich-鸵鸟 ...

  3. 也说python的类--基于python3.5

    在面向对象的语言中,除了方法.对象,剩下的一大重点就是类了,从意义上来讲,类就是对具有相同行为对象的归纳.当一个或多个对象有相同属性.方法等共同特征的时候,我们就可以把它归纳到同一个类当中.在使用上来 ...

  4. python3 入门 (四) 类与继承

    Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. p ...

  5. 慕课python3.5学习笔记

    本文章中有部分代码为python2 慕课python入门 慕课python进阶 布尔值 布尔值可以用and.or和not运算. and运算是与运算,只有所有都为 True,and运算结果才是 True ...

  6. python3之面向对象

    1.面向对象术语 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类属性(类变量):类属性在整个实例化的对象中是公用的.类属 ...

  7. python3操作socketserver

    socketserver是标准库中的一个高级模块,用于网络客户端与服务器的实现.模块中,已经实现了一些可供使用的类. 在python3中,导入socketserver模块使用的命令: import s ...

  8. Python面向对象——多重继承大揭秘

    1如果如图所示使用多重继承,我们将看到什么 2我们看到了基类被执行了两次Baseclass 3代码验证吧 class BaseClass: num_base_calls = 0 def call_me ...

  9. Python2和Python3的差异

    之前做Spark大数据分析的时候,考虑要做Python的版本升级,对于Python2和Python3的差异做了一个调研,主要对于语法和第三方工具包支持程度进行了比较. 基本语法差异 核心类差异 Pyt ...

  10. 小甲鱼Python3笔记

    000-愉快的开始 入门容易,学习难,代码量少. 跨平台: Windows, Mac OS, Linux, UNIX. 应用领域: 操作系统 WEB 3D动画 企业应用 云计算等等. 001-我和Py ...

随机推荐

  1. SpringBoot整合Shiro实现权限控制,验证码

    本文介绍 SpringBoot 整合 shiro,相对于 Spring Security 而言,shiro 更加简单,没有那么复杂. 目前我的需求是一个博客系统,有用户和管理员两种角色.一个用户可能有 ...

  2. 转载 用ShadowVolume画模型的影子

    阅读目录(Content) Shadow Volume 包围盒 动态生成包围盒 判断 多光源下的阴影 总结 问题 CSharpGL(48)用ShadowVolume画模型的影子 回到顶部(go to ...

  3. 多变量分析绘图(hue参数)以及盒图和小提琴图

    1,函数stipplot() stipplot()函数用来画散点图,其x轴是离散型的变量 直接上代码 import seaborn as sns import numpy as np import p ...

  4. 【Go语言】map在goroutine通信中的使用问题

    简介 本篇文章的主要内容是解决go语言map在使用中遇到的两个问题,对于初学者是不可避免的坑 一.cannot assign to struct field 当map中存在struct类型的成员,如果 ...

  5. Java中字母大小写的转换

    例:String str = "AbC"; 把字符串所有字母变成小写: System.out.println(str.toLowerCase()); 把字符串所有字母大写: Sys ...

  6. 红帽学习笔记[RHCSA] 第六课[进程、服务相关]

    第六课 进程 进程:已经启动的可执行程序的运行中的实例.每个进程都有自己的地址空间,并占用了一定的系统资源. 如何产生一个进程 执行程序或命令 计划任务 在终端中对进程管理 运行一个前台进程 [roo ...

  7. Java第五周作业+总结

    实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is a test of java".按要求执 ...

  8. 如何有效的使用google进行搜索的20个技能

    每天有数百万人因为各种各样的原因使用谷歌搜索.学生们把它用于学校,商人们把它用于研究,还有数百万人把它用于娱乐.但大多数人可能没有充分利用谷歌搜索的潜力. 想要更有效地使用谷歌搜索,并得到您想要的搜索 ...

  9. 华南理工大学 “三七互娱杯” G HRY and tree

    https://ac.nowcoder.com/acm/contest/874/G 题目大意:对于一个连通图,现在定义两个点的贡献为连接两点的路径上最大的权值 求任意两个点贡献的和 这个题看懂花了我很 ...

  10. [转帖]Docker从入门到动手实践

    Docker从入门到动手实践 https://www.cnblogs.com/nsky/p/10853194.html dockerfile的图很好呢. 但是自己没有做实验 , 其实知识都挺好. do ...