浅析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 相关文章推荐
phpsir 开发 一个检测百度关键字网站排名的python 程序
Sep 17 Python
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
Jun 10 Python
python实现RSA加密(解密)算法
Feb 17 Python
python处理Excel xlrd的简单使用
Sep 12 Python
Python 12306抢火车票脚本
Feb 07 Python
python如何实现int函数的方法示例
Feb 19 Python
用python实现百度翻译的示例代码
Mar 09 Python
python3使用SMTP发送HTML格式邮件
Jun 19 Python
Python实现base64编码的图片保存到本地功能示例
Jun 22 Python
Python Socket编程之多线程聊天室
Jul 28 Python
python实现操作文件(文件夹)
Oct 31 Python
Python爬取英雄联盟MSI直播间弹幕并生成词云图
Jun 01 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&&mysql)六
2006/10/09 PHP
PHP中的extract的作用分析
2008/04/09 PHP
php强制文件下载而非在浏览器打开的自定义函数分享
2014/05/08 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
jQuery的一些特性和用法整理小结
2010/01/13 Javascript
jQuery 操作下拉列表框实现代码
2010/02/22 Javascript
$.format,jquery.format 使用说明
2011/07/13 Javascript
jquery使用经验小结
2015/05/20 Javascript
JS+CSS实现下拉列表框美化效果(3款)
2015/08/15 Javascript
浅谈JavaScript中数组的增删改查
2016/06/20 Javascript
JS比较两个数值的大小实例
2016/11/25 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
2017/01/18 Javascript
jQuery插件autocomplete使用详解
2017/02/04 Javascript
Angular实现预加载延迟模块的示例
2017/10/12 Javascript
详解Nuxt.js部署及踩过的坑
2018/08/07 Javascript
微信小程序如何再次获取用户授权的方法
2019/05/10 Javascript
node.js制作一个简单的登录拦截器
2020/02/10 Javascript
javascript+css实现进度条效果
2020/03/25 Javascript
在VUE style中使用data中的变量的方法
2020/06/19 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
echarts柱状图背景重叠组合而非并列的实现代码
2020/12/10 Javascript
JS实现百度搜索框
2021/02/25 Javascript
pyqt4教程之widget使用示例分享
2014/03/07 Python
跟老齐学Python之通过Python连接数据库
2014/10/28 Python
Python实现读取字符串按列分配后按行输出示例
2018/04/17 Python
Python中常用的8种字符串操作方法
2019/05/06 Python
python颜色随机生成器的实例代码
2020/01/10 Python
python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)
2021/02/19 Python
为什么要做架构设计
2015/07/08 面试题
学生会竞选自荐信
2013/10/12 职场文书
校庆筹备方案
2014/03/30 职场文书
环卫处个人工作总结
2015/03/04 职场文书
幼儿园食品安全责任书
2015/05/08 职场文书
Pytorch实现图像识别之数字识别(附详细注释)
2021/05/11 Python
2022年四月新番
2022/03/15 日漫