浅析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 threading多线程编程实例
Sep 18 Python
Python中使用第三方库xlutils来追加写入Excel文件示例
Apr 05 Python
python 多线程对post请求服务器测试并发的方法
Jun 13 Python
python交互模式下输入换行/输入多行命令的方法
Jul 02 Python
python使用Qt界面以及逻辑实现方法
Jul 10 Python
Pandas中DataFrame的分组/分割/合并的实现
Jul 16 Python
Tensorflow模型实现预测或识别单张图片
Jul 19 Python
django queryset相加和筛选教程
May 18 Python
python中time.ctime()实例用法
Feb 03 Python
python实现图片转字符画
Feb 19 Python
详细总结Python常见的安全问题
May 21 Python
Python使用PyYAML库读写yaml文件的方法
Apr 06 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
MyEclipse常用配置图文教程
2014/09/11 PHP
PHP 接入微信扫码支付总结(总结篇)
2016/11/03 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
Thinkphp5行为使用方法汇总
2017/12/21 PHP
Laravel框架模板继承操作示例
2018/06/11 PHP
javascript生成/解析dom的CDATA类型的字段的代码
2007/04/22 Javascript
Javascript遍历Html Table示例(包括内容和属性值)
2014/07/08 Javascript
js使用DOM操作实现简单留言板的方法
2015/04/10 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
浅析JavaScript声明变量
2015/12/21 Javascript
详解JavaScript异步编程中jQuery的promise对象的作用
2016/05/03 Javascript
移动端 一个简单易懂的弹出框
2016/07/06 Javascript
基于bootstrap的选择框插件icheck
2016/12/23 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
浅谈vue父子组件怎么传值
2018/07/21 Javascript
详解vue中的父子传值双向绑定及数据更新问题
2019/06/13 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
浅谈vue生命周期共有几个阶段?分别是什么?
2020/08/07 Javascript
基于javascript原生判断DOM是否加载完毕
2020/10/14 Javascript
Vue中用JSON实现刷新界面不影响倒计时
2020/10/26 Javascript
基于vue实现微博三方登录流程解析
2020/11/04 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
JavaScript缓动动画函数的封装方法
2020/11/25 Javascript
Django实现自定义404,500页面教程
2017/03/26 Python
Python3 批量扫描端口的例子
2019/07/25 Python
Python实现把多维数组展开成DataFrame
2019/11/30 Python
Python递归函数特点及原理解析
2020/03/04 Python
借助Paramiko通过Python实现linux远程登陆及sftp的操作
2020/03/16 Python
财务会计人员岗位职责
2013/11/30 职场文书
十佳大学生村官事迹
2014/01/09 职场文书
学生自我评价范文
2014/02/02 职场文书
餐厅经理岗位职责和岗位目标
2014/02/13 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
党员国庆节演讲稿范文2014
2014/09/21 职场文书
庆祝儿童节标语
2014/10/09 职场文书
初二物理教学反思
2016/02/19 职场文书