浅析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 相关文章推荐
Python的Django框架中的表单处理示例
Jul 17 Python
详解tensorflow载入数据的三种方式
Apr 24 Python
Python实现的爬取网易动态评论操作示例
Jun 06 Python
浅谈Series和DataFrame中的sort_index方法
Jun 07 Python
python生成带有表格的图片实例
Feb 03 Python
python IDLE 背景以及字体大小的修改方法
Jul 12 Python
Pytorch Tensor的索引与切片例子
Aug 18 Python
python lambda表达式在sort函数中的使用详解
Aug 28 Python
python GUI库图形界面开发之pyinstaller打包python程序为exe安装文件
Feb 26 Python
python实现发送QQ邮件(可加附件)
Dec 23 Python
Django显示可视化图表的实践
May 10 Python
python实现简单聊天功能
Jul 07 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
基于MySQL体系结构的分析
2013/05/02 PHP
PHP记录页面停留时间的方法
2016/03/30 PHP
Yii2.0表关联查询实例分析
2016/07/18 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
PHP实现文件上传操作和封装
2020/03/04 PHP
PHP sdk实现在线打包代码示例
2020/12/09 PHP
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
爱恋千雪-US-AscII加密解密工具(网页加密)下载
2007/06/06 Javascript
javascript html 静态页面传参数
2009/04/10 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
jQuery UI插件实现百度提词器效果
2016/11/21 Javascript
Bootstrap组合上、下拉框简单实现代码
2017/03/06 Javascript
angular.extend方法的具体使用
2017/09/14 Javascript
微信小程序自定义组件的实现方法及自定义组件与页面间的数据传递问题
2018/10/09 Javascript
vue2.0基于vue-cli+element-ui制作树形treeTable
2019/04/30 Javascript
vue中created和mounted的区别浅析
2019/08/13 Javascript
Node.js API详解之 assert模块用法实例分析
2020/05/26 Javascript
使用原生javascript开发计算器实例代码
2021/02/21 Javascript
[00:12]DAC2018 Miracle-站上中单舞台,他能否再写奇迹?
2018/04/06 DOTA
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
一个超级简单的python web程序
2014/09/11 Python
Python3多线程操作简单示例
2018/05/22 Python
numpy中矩阵合并的实例
2018/06/15 Python
Python 判断图像是否读取成功的方法
2019/01/26 Python
对YOLOv3模型调用时候的python接口详解
2019/08/26 Python
pytorch 数据处理:定义自己的数据集合实例
2019/12/31 Python
Python新手如何理解循环加载模块
2020/05/29 Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
2020/08/04 Python
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
爱普生美国官网:Epson美国
2018/11/05 全球购物
汽车专业大学生职业生涯规划范文
2014/01/07 职场文书
投标人廉洁自律承诺书
2014/05/26 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
Python+Selenium自动化环境搭建与操作基础详解
2022/03/13 Python
十大最强岩石系宝可梦,怪颚龙实力最强,第七破坏力很强
2022/03/18 日漫