浅析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获取运行目录与当前脚本目录的方法
Jun 01 Python
Python实现代码统计工具(终极篇)
Jul 04 Python
Python Json模块中dumps、loads、dump、load函数介绍
May 15 Python
Python的高阶函数用法实例分析
Apr 11 Python
python使用装饰器作日志处理的方法
Jul 11 Python
django mysql数据库及图片上传接口详解
Jul 18 Python
python框架django项目部署相关知识详解
Nov 04 Python
Python 一行代码能实现丧心病狂的功能
Jan 18 Python
在 Pycharm 安装使用black的方法详解
Apr 02 Python
Python使用Pyqt5实现简易浏览器(最新版本测试过)
Apr 27 Python
PyPDF2读取PDF文件内容保存到本地TXT实例
May 12 Python
Elasticsearch py客户端库安装及使用方法解析
Sep 14 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
农民和部队如何穿矿
2020/03/04 星际争霸
攻克CakePHP系列二 表单数据显示
2008/10/22 PHP
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
php中unserialize返回false的解决方法
2014/09/22 PHP
PHP开启目录引索+fancyindex漂亮目录浏览带搜索功能
2019/09/23 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
破解Session cookie的方法
2006/07/28 Javascript
js每次Title显示不同的名言
2008/09/25 Javascript
一次失败的jQuery优化尝试小结
2011/02/06 Javascript
javascript如何实现暂停功能
2015/11/06 Javascript
基于JavaScript实现随机颜色输入框
2016/12/10 Javascript
jquery.masonry瀑布流效果
2017/05/25 jQuery
AngularJs 禁止模板缓存的方法
2017/11/28 Javascript
mui框架 页面无法滚动的解决方法(推荐)
2018/01/25 Javascript
vue项目首屏打开速度慢的解决方法
2019/03/31 Javascript
Vue Autocomplete 自动完成功能简单示例
2019/05/25 Javascript
node命令行工具之实现项目工程自动初始化的标准流程
2019/08/12 Javascript
基于Vue el-autocomplete 实现类似百度搜索框功能
2019/10/25 Javascript
原生JS运动实现轮播图
2021/01/02 Javascript
[48:52]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第一局
2016/02/25 DOTA
Python中不同进制的语法及转换方法分析
2016/07/27 Python
python使用TensorFlow进行图像处理的方法
2018/02/28 Python
python 反向输出字符串的方法
2018/07/16 Python
Face++ API实现手势识别系统设计
2018/11/21 Python
15行Python代码实现网易云热门歌单实例教程
2019/03/10 Python
PyCharm如何导入python项目的方法
2020/02/06 Python
Python 绘制可视化折线图
2020/07/22 Python
Django中的DateTimeField和DateField实现
2021/02/24 Python
CSS3 Flexbox中flex-shrink属性的用法示例介绍
2013/12/30 HTML / CSS
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
享誉全球的多元化时尚精品购物平台:Farfetch发发奇(支持中文)
2017/08/08 全球购物
商场拾金不昧表扬信
2014/01/13 职场文书
《童趣》教学反思
2014/02/19 职场文书
夏季药店促销方案
2014/08/22 职场文书
2014年卫生院工作总结
2014/12/03 职场文书
单身狗福利?Python爬取某婚恋网征婚数据
2021/06/03 Python