浅析Python中的多重继承


Posted in Python onApril 28, 2015

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

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

  1.     Dog - 狗狗;
  2.     Bat - 蝙蝠;
  3.     Parrot - 鹦鹉;
  4.     Ostrich - 鸵鸟。

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

浅析Python中的多重继承

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

浅析Python中的多重继承

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

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

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

浅析Python中的多重继承

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

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

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

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

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。

为了更好地看出继承关系,我们把Runnable和Flyable改为RunnableMixin和FlyableMixin。类似的,你还可以定义出肉食动物CarnivorousMixin和植食动物HerbivoresMixin,让某个动物同时拥有好几个Mixin:

class Dog(Mammal, RunnableMixin, CarnivorousMixin):
  pass

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

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

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

class MyTCPServer(TCPServer, ForkingMixin):
  pass

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

class MyUDPServer(UDPServer, ThreadingMixin):
  pass

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

class MyTCPServer(TCPServer, CoroutineMixin):
  pass

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

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

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

Python 相关文章推荐
Python3.x中自定义比较函数
Apr 24 Python
windows系统下Python环境的搭建(Aptana Studio)
Mar 06 Python
Python中的浮点数原理与运算分析
Oct 12 Python
Python探索之ModelForm代码详解
Oct 26 Python
使用Python来开发微信功能
Jun 13 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
Dec 18 Python
Python小程序之在图片上加入数字的代码
Nov 26 Python
python实现信号时域统计特征提取代码
Feb 26 Python
找Python安装目录,设置环境路径以及在命令行运行python脚本实例
Mar 09 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
Jun 28 Python
python3 实现mysql数据库连接池的示例代码
Apr 17 Python
python使用openpyxl库读写Excel表格的方法(增删改查操作)
May 02 Python
python输出当前目录下index.html文件路径的方法
Apr 28 #Python
Python实现基于权重的随机数2种方法
Apr 28 #Python
python使用urllib2实现发送带cookie的请求
Apr 28 #Python
python实现在windows下操作word的方法
Apr 28 #Python
介绍Python的@property装饰器的用法
Apr 28 #Python
Pyhthon中使用compileall模块编译源文件为pyc文件
Apr 28 #Python
在Python中使用__slots__方法的详细教程
Apr 28 #Python
You might like
PHP数据库开发知多少
2006/10/09 PHP
php获取某个目录大小的代码
2008/09/10 PHP
PHP-redis中文文档介绍
2013/02/07 PHP
PHP导出Excel实例讲解
2016/01/24 PHP
指定位置如果有图片显示图片,无图片显示广告的JS
2010/06/05 Javascript
关于jquery的多个选择器的使用示例
2013/10/18 Javascript
javaScript年份下拉列表框内容为当前年份及前后50年
2014/05/28 Javascript
3个可以改善用户体验的AngularJS指令介绍
2015/06/18 Javascript
JavaScript隐式类型转换
2016/03/15 Javascript
JS Ajax请求如何防止重复提交
2016/06/13 Javascript
浅谈javascript:两种注释,声明变量,定义函数
2016/09/29 Javascript
前端js弹出框组件使用方法
2020/08/24 Javascript
javascript自执行函数
2017/02/10 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
2017/05/26 Javascript
原生JavaScript来实现对dom元素class的操作方法(推荐)
2017/08/16 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
echarts浮动显示单位的实现方法示例
2020/12/04 Javascript
[01:02]2014 DOTA2国际邀请赛中国区预选赛 现场抢先看
2014/05/22 DOTA
[01:04:39]OG vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[08:54]DOTA2-DPC中国联赛 正赛 Aster vs LBZS 选手采访
2021/03/11 DOTA
python dict remove数组删除(del,pop)
2013/03/24 Python
Django的数据模型访问多对多键值的方法
2015/07/21 Python
Python图像处理之简单画板实现方法示例
2018/08/30 Python
python 读取文件并把矩阵转成numpy的两种方法
2019/02/12 Python
对python中的os.getpid()和os.fork()函数详解
2019/08/08 Python
利用Python绘制Jazz网络图的例子
2019/11/21 Python
在Tensorflow中查看权重的实现
2020/01/24 Python
opencv+python实现均值滤波
2020/02/19 Python
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
大学生自荐信
2013/12/11 职场文书
企业管理部经理岗位职责
2013/12/24 职场文书
2015年党风廉政建设责任书
2015/01/29 职场文书
大学考试作弊检讨书
2015/05/06 职场文书
财务会计个人原因辞职信
2019/06/21 职场文书
企业内部管理控制:采购授权审批制度范本
2020/01/19 职场文书
python实现会员信息管理系统(List)
2022/03/18 Python