Python高级教程-多重继承
多重继承
继承是面向对象编程的一个重要的方式,因为通过继承,子类可以扩展父类的功能。
Animal类的层次设计,假设要实现以下4中动物:
- Dog - 狗狗;
- Bat - 蝙蝠;
- Parrot - 鹦鹉;
- Ostrich - 鸵鸟
如果按照哺乳类和鸟类来分:

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

如果把上面的两种分类都包含进来,就得设计更多的层次:
- 哺乳类:能跑的哺乳类,能飞的哺乳类;
- 鸟类:能跑的鸟类,能飞的鸟类。
这么一来,类的层次就复杂了。正确的做法是采用多重继承。首先主要的类层次仍然是按照哺乳类和鸟类设计:
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...')
对于需要Rnnnable功能的动物,就多继承一个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这两类网络服务,而同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMinIn和ThreadingMixIn提供。通过组合,即可以创造合适的服务来。
比如编写一个多进程模式的TCP服务,定义如下:
class MyTCPServer(TCPServer, ForkingMixIn):
pass
编写一个多线程模式的UDP服务,定义如下:
class MyUDPServer(UDPServer, ThreadingMixIn):
pass
这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。
总结
由于Python允许使用多重继承,因此MixIn就是一种常见的设计。
只允许单一继承的语言(如Java)不能使用MixIn的设计。
Python高级教程-多重继承的更多相关文章
- Python高级教程
关键字is 和 == 的区别 a = 'hello world' b = 'hello world' a == b #返回True a is b #返回False 注意:is 判断是否是一个ID, = ...
- Python高级教程-sorted
Python中的排序算法 排序是程序中经常用到的算法.通常规定,对于两个元素x和y,如果认为x<y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法 ...
- Python高级教程-filter
Python中的filter() Python内建的filter()函数用于过滤序列.和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次 ...
- Python高级教程-Map/Reduce
Python中的map()和reduce() Python内建了map()和reduce()函数. map() map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每 ...
- Python高级教程-高阶函数
Higher-order function(高阶函数) 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下代码: >>> abs(-10) 10 但 ...
- Python高级教程-生成器
生成器(Generator) 通过列表生成式,可以直接创建一个列表.但是,受内存限制,列表的容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几 ...
- Python高级教程-列表生成式
List Comprehensions(列表生成式) 列表生成式,是Python内置的非常简单却强大的可以用来创建list的生成式. 例如,要生成list:[1,2,3,4,5,6,7,8,9,10] ...
- Python高级教程-迭代
Python中的迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Iteration). 在Python中,迭代是通过for...in ...
- Python高级教程-切片
Python中的切片 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: >>> L = ['A','B','C','D'] 对经常取指定索引范围的操作, ...
随机推荐
- 启动BusyBox内建的FTP Server
启动BusyBox内建的FTP Server 要启动BusyBox内建的FTP Server,我们需要先孰悉tcpsvd与ftpd这两个命令. tcpsvd可以建立TCP socket,并将它bi ...
- 浅谈HTTP中Get与Post的区别_转
可参考:HTTP请求中POST与GET的区别 Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个UR ...
- 科技巨头们以 "A" 取名的时尚潮流
科技巨头们以 "A" 取名的时尚潮流 from 公众号 WebHub 世界上有许多巨头公司喜欢以字母 a 打头作公司起名.改名,这主要是因为电话薄是以字母排序的(外国人习惯家里 ...
- js实现div的置底
//-------------置底的div---------------------- <div class="mui-content lv-mrcd" id=" ...
- Unity3D项目之 Survival Shooter 记录
1.导入资源 2.把预设文件的环境拖到场景中, 3.位置归0 4.保存场景 5.删除默认灯光,把预设灯光拖到场景中,位置归0 6.新建一个 Quad 7.旋转90度,设置缩放100,100,1 重命名 ...
- 【UVa】Partitioning by Palindromes(dp)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=27&page=sh ...
- JAVA基础之訪问控制权限(封装)
包:库单元 1.当编写一个Java源码文件时.此文件通常被称为编译单元(有时也被称为转译单元). 2.每一个编译单元都必须有一个后缀名.java,而在编译单元内则能够有一个public类,该类名称必须 ...
- CSDN日报20170411 ——《怎样给自己的私活项目标价》
[程序人生]怎样给自己的私活项目标价 作者:瞬息之间 非常早之前讲过我们"怎么接私活的心得技巧".相信非常多同学听了心里痒痒的.据我认识的(无论是现实生活还是网上接触的)朋友来看. ...
- Object Slicing in C++
In C++, a derived class object can be assigned to base class, but the other way is not possible. cla ...
- thinkphp5如何使用layout
thinkphp5的layout和以前的版本有点差异. 首先开启配置文件中的 'template' => [ 'layout_on' => true, // 'layo ...