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

  现在,我们要给动物再加上RunnableFlyable的功能,只需要先定义好RunnableFlyable的类:

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。

  为了更好地看出继承关系,我们把RunnableFlyable改为RunnableMixInFlyableMixIn。类似的,你还可以定义出肉食动物CarnivorousMixIn和植食动物HerbivoresMixIn,让某个动物同时拥有好几个MixIn:

class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
pass

  

  MixIn的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系

  Python自带的很多库也使用了MixIn。举个例子,Python自带了TCPServerUDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixInThreadingMixIn提供。通过组合,我们就可以创造出合适的服务来。

  比如,编写一个多进程模式的TCP服务,定义如下:

class MyTCPServer(TCPServer, ForkingMixIn):
pass

  编写一个多线程模式的UDP服务,定义如下:

class MyUDPServer(UDPServer, ThreadingMixIn):
pass

  如果你打算搞一个更先进的协程模型,可以编写一个CoroutineMixIn

class MyTCPServer(TCPServer, CoroutineMixIn):
pass

  这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

小结

  由于Python允许使用多重继承,因此,MixIn就是一种常见的设计

  只允许单一继承的语言(如Java)不能使用MixIn的设计。

python基础——多重继承的更多相关文章

  1. python 基础——多重继承

    原始的初始化 子类直接调用超类 __init__ 方法初始化,当形成钻石继承的时候,超类会被多次初始化,可能会有意向不到的问题: BaseClass /        \ OneClass    Tw ...

  2. python基础之面向对象高级编程

    面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个"函数"供使用(可以讲多函数中公用的变量封装到对象中) ...

  3. Python基础+Pythonweb+Python扩展+Python选修四大专题 超强麦子学院Python35G视频教程

    [保持在百度网盘中的, 可以在观看,嘿嘿 内容有点多,要想下载, 回复后就可以查看下载地址,资源收集不易,请好好珍惜] 下载地址:http://www.fu83.cc/ 感觉文章好,可以小手一抖 -- ...

  4. Python基础s14-day1

    2016年7月23日"Python基础s14-Day1" Python是什么? Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/),是一种面向对象.直译式 ...

  5. python基础——使用元类

    python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...

  6. Python 基础语法(三)

    Python 基础语法(三) --------------------------------------------接 Python 基础语法(二)------------------------- ...

  7. Python基础教程【读书笔记】 - 2016/7/4

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第二波:第7章  更加抽象 [总览] 创建自己的对象,是Python的核心概念!Python被称为面向对象的语言.介绍如 ...

  8. Python基础教程 - Tdcqma

      1.1 普通字符串 1.21 错误与异常 1.41 XXXXXX 1.61 XXXXXX 1.81 XXXXXX 1.101 XXXXXX 1.2 转义字符串 1.22 装饰器         1 ...

  9. python基础语法及知识点总结

    本文转载于星过无痕的博客http://www.cnblogs.com/linxiangpeng/p/6403991.html 在此表达对原创作者的感激之情,多谢星过无痕的分享!谢谢! Python学习 ...

随机推荐

  1. 第二天 django apache

    1. 475  brew tap homebrew/apache 476  brew install mod_wsgi 477  ls /usr/local/Cellar/mod_wsgi/4.5.7 ...

  2. SQLite 数据库调研

    SQLite数据库的特点(转载的): ★技术上的优点和特性 SQLite是一个轻量级.跨平台的关系型数据库.既然号称关系型数据库,支持SQL92标准中常用的玩意儿(比如视图.事务.触发器等)就是理所当 ...

  3. ajax读取XML文本(如读取城市)

    //加载城市 function loadArea_pep() { $.ajax({ url: "/xmlFile/crty.xml", success: function (res ...

  4. CentOS-6.5-saltstack-安装

    官方网站:https://www.saltstack.com/ 官方文档   https://docs.saltstack.cn/contents.html GitHub:  https://gith ...

  5. iOS开发——高级篇——内存分析,Instruments

    一.内存分析 1.静态内存分析(Analyze)不运行程序,直接对代码进行内存分析,查看代码是否有内存泄露优点:分析速度快,并且可以对所有的代码进行内存分析缺点:分析结果不一定准确(没有运行程序,根据 ...

  6. Caffe学习系列(15):添加新层

    如何在Caffe中增加一层新的Layer呢?主要分为四步: (1)在./src/caffe/proto/caffe.proto 中增加对应layer的paramter message: (2)在./i ...

  7. 顺序栈的c++实现及利用其实现括号的匹配

    #include<iostream>#include<cassert>#include<cstring>#include<string>using na ...

  8. 一个按比特位拷贝数据的函数copybits

    一个按比特位拷贝数据的函数 没有进行特别的优化.其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化. 说明 这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷 ...

  9. ndk学习11: linux内存管理

        1. 进程地址空间   2.内存管理     栈上分配空间 alloca()       栈上分配大小 strdupa()    拷贝一个字符串到栈上(显然这个函数不安全)           ...

  10. Objective C 快速入门学习二

    Objective-C 类.对象.方法 1.编写一个复数类: #import <Foundation/Foundation.h>@interface Complex: NSObject / ...