多继承

class ShenXian: # 神仙def fei(self):print("神仙都会⻜")
class Monkey: # 猴def chitao(self):print("猴⼦喜欢吃桃⼦")
class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴pass
sxz = SunWukong() # 孙悟空
sxz.chitao() # 会吃桃⼦
sxz.fei() # 会⻜

  此时, 孙悟空是⼀只猴⼦, 同时也是⼀个神仙. 那孙悟空继承了这两个类. 孙悟空⾃然就可以执⾏这两个类中的⽅法. 多继承⽤起来简单. 也很好理解. 但是多继承中, 存在着这样⼀个问题. 当两个⽗类中出现了重名⽅法的时候. 这时该怎么办呢? 这时就涉及到如何查找⽗类⽅法的这么⼀个问题.即MRO(method resolution order) 问题. 在python中这是⼀个很复杂的问题. 因为在不同的python版本中使⽤的是不同的算法来完成MRO的.

这里需要补充一下python中类的种类(继承需要):

在python2x版本中存在两种类.:
  ⼀个叫经典类. 在python2.2之前. ⼀直使⽤的是经典类. 经典类在基类的根如果什么都不写.
  ⼀个叫新式类. 在python2.2之后出现了新式类. 新式类的特点是基类的根是object类。
python3x版本中只有一种类:
python3中使⽤的都是新式类. 如果基类谁都不继承. 那这个类会默认继承 object

1经典类的多继承

虽然在python3中已经不存在经典类了. 但是经典类的MRO最好还是学⼀学. 这是⼀种树形结构遍历的⼀个最直接的案例. 在python的继承体系中. 我们可以把类与类继承关系化成⼀个树形结构的图. 来, 上代码:

代码示例

对付这种mro画图就可以:

继承关系图已经有了. 那如何进⾏查找呢? 记住⼀个原则. 在经典类中采⽤的是深度优先,遍历⽅案. 什么是深度优先. 就是⼀条路走到头. 然后再回来. 继续找下⼀个.

图中每个圈都是准备要送鸡蛋的住址. 箭头和⿊线表⽰线路. 那送鸡蛋的顺序告诉你入⼝在最下⾯R. 并且必须从左往右送. 那怎么送呢?

如图. 肯定是按照123456这样的顺序来送. 那这样的顺序就叫深度优先遍历. ⽽如果是142356呢? 这种被称为⼴度优先遍历. 好了. 深度优先就说这么多. 那么上⾯那个图怎么找的呢? MRO是什么呢? 很简单. 记住. 从头开始. 从左往右. ⼀条路跑到头, 然后回头. 继续⼀条路跑到头. 就是经典类的MRO算法.

类的MRO: Foo-> H -> G -> F -> E -> D -> B -> A -> C. 你猜对了么?

2新式类的多继承

2.1 mro序列

MRO是一个有序列表L,在类被创建时就计算出来。
通用计算公式为:

mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )(其中Child继承自Base1, Base2)

如果继承至一个基类:class B(A)
这时B的mro序列为

mro( B ) = mro( B(A) )
= [B] + merge( mro(A) + [A] )
= [B] + merge( [A] + [A] )
= [B,A]

如果继承至多个基类:class B(A1, A2, A3 …)
这时B的mro序列

mro(B) = mro( B(A1, A2, A3 …) )
= [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] )
= ...

计算结果为列表,列表中至少有一个元素即类自己,如上述示例[A1,A2,A3]。merge操作是C3算法的核心。

2.2. 表头和表尾
表头:
  列表的第一个元素

表尾:
  列表中表头以外的元素集合(可以为空)

示例
  列表:[A, B, C]
  表头是A,表尾是B和C

2.3. 列表之间的+操作
+操作:

[A] + [B] = [A, B]
(以下的计算中默认省略)
---------------------

merge操作示例:

如计算merge( [E,O], [C,E,F,O], [C] )
有三个列表 :  ①      ②          ③1 merge不为空,取出第一个列表列表①的表头E,进行判断                              各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
2 取出列表②的表头C,进行判断C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
3 进行下一次新的merge操作 ......
--------------------- 

计算mro(A)方式:

mro(A) = mro( A(B,C) )原式= [A] + merge( mro(B),mro(C),[B,C] )mro(B) = mro( B(D,E) )= [B] + merge( mro(D), mro(E), [D,E] )  # 多继承= [B] + merge( [D,O] , [E,O] , [D,E] )  # 单继承mro(D(O))=[D,O]= [B,D] + merge( [O] , [E,O]  ,  [E] )  # 拿出并删除D= [B,D,E] + merge([O] ,  [O])= [B,D,E,O]mro(C) = mro( C(E,F) )= [C] + merge( mro(E), mro(F), [E,F] )= [C] + merge( [E,O] , [F,O] , [E,F] )= [C,E] + merge( [O] , [F,O]  ,  [F] )  # 跳过O,拿出并删除= [C,E,F] + merge([O] ,  [O])= [C,E,F,O]原式= [A] + merge( [B,D,E,O], [C,E,F,O], [B,C])= [A,B] + merge( [D,E,O], [C,E,F,O],   [C])= [A,B,D] + merge( [E,O], [C,E,F,O],   [C])  # 跳过E= [A,B,D,C] + merge([E,O],  [E,F,O])= [A,B,D,C,E] + merge([O],    [F,O])  # 跳过O= [A,B,D,C,E,F] + merge([O],    [O])= [A,B,D,C,E,F,O]
--------------------- 

结果OK. 那既然python提供了. 为什么我们还要如此⿇烦的计算MRO呢? 因为笔
试.......你在笔试的时候, 是没有电脑的. 所以这个算法要知道. 并且简单的计算要会. 真是项⽬
开发的时候很少有⼈这么去写代码.

这个说完了. 那C3到底怎么看更容易呢? 其实很简单. C3是把我们多个类产⽣的共同继
承留到最后去找. 所以. 我们也可以从图上来看到相关的规律. 这个要⼤家⾃⼰多写多画图就
能感觉到了. 但是如果没有所谓的共同继承关系. 那⼏乎就当成是深度遍历就可以了

转载于:https://www.cnblogs.com/YZL2333/p/10324169.html

Python3 面向对象之:多继承相关推荐

  1. python菜鸟基础教程-Python3 面向对象

    Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触 ...

  2. python 菜鸟-Python3 面向对象

    Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触 ...

  3. python面向对象思路_Python面向对象三要素-继承(Inheritance)

    Python面向对象三要素-继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承概述 1>.基本概念 前面我们学习了Python的面向对象三 ...

  4. python3面向对象_Python3面向对象编程

    Python3面向对象编程 编辑 锁定 讨论 上传视频 <Python3面向对象编程>是2015年6月电子工业出版社出版的图书,作者是肖鹏,常贺,石琳. 书    名 Python3面向对 ...

  5. Python3 面向对象编程

    好记性不如烂笔头,对之前阅读书籍进行梳理与总结,此文为<Python3面向对象编程>阅读笔记. 文章目录 第一章 面向对象设计 第二章 Python对象 第三章 对象相似时 第四章 异常捕 ...

  6. python3面向对象学习

    python3面向对象学习 面向对象 面向对象技术简介 类定义 类对象 self代表类的实例,而非类 类的方法 继承 多继承 方法重写 类属性与方法 类的私有属性 类的方法 类的私有方法 运算符重载 ...

  7. 面向对象-封装、继承、多态

    面向对象-封装.继承.多态 面向对象-封装 一.封装: private 数据类型 _名字;   --成员变量 public 默认一致 名字 属性 {  get{ return _名字; }  set{ ...

  8. Python基础day09【面向对象(封装、继承、多态)、重写、私有权限】

    视频.源码.课件.软件.笔记:超全面Python基础入门教程[十天课程]博客笔记汇总表[黑马程序员] Python基础day09[面向对象(封装.继承.多态).重写.私有权限] Python基础day ...

  9. JavaScript面向对象——理解构造函数继承(类继承)

    JavaScript面向对象--理解构造函数继承(类继承) 构造函数式继承(类继承) function SuperClass(id) {// 引用类型公有属性this.books = ['JavaSc ...

  10. JavaScript中OOP——面向对象中的继承/闭包

      前  言  OOP  JavaScript中OOP-->>>面向对象中的继承/闭包 1.1面向对象的概念 使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方法.      ...

最新文章

  1. jQuery火箭图标返回顶部代码
  2. php300类库,扩展类库 · PHP300FrameWork · 看云
  3. Redis 持久化(persistence)
  4. oracle左连接没用_oracle左外连接不显示正确的空值
  5. SpringBoot 2 集成微信扫码支付
  6. iframe调用父页面方法_5.1 vue中子组件调用父组件的方法,务必理解自定义事件的重要性...
  7. 计算机word怎么选中全文,word怎么选择 WORD怎么选取全文
  8. 隔年增长的题_行测技巧:资料分析隔年增长问题
  9. ●POJ 1228 Grandpas Estate
  10. DataSource接口 Connection pooling(连接池
  11. K3C官改固件更新frp客户端
  12. [转载]矩阵求导运算规则
  13. 龙芯cpu linux恢复密码,中标麒麟(龙芯CPU)--忘记root密码怎么修改?
  14. python系统开发_证券交易系统设计与开发
  15. K8S教程(7)使用探针对容器进行健康检查
  16. 毕业论文开题报告模板
  17. vue 仿网易云音乐项目
  18. 阅读用户思维的思考。
  19. java 中心度_任务调度中心 (优化版)【原】
  20. WebRTC源码研究(4)web服务器工作原理和常用协议基础

热门文章

  1. 列举python内置函数和使用方法_python学习交流 - 内置函数使用方法和应用举例
  2. 烈火如歌手游找回服务器,《烈火如歌》05月02日新服公告:侠肝义胆
  3. php 26进制转10进制,PHP 10进制转62进制
  4. ext3日志模式---文件系统
  5. 【2020CCPC秦皇岛:C】Cameraman(计算几何+思维+枚举)
  6. 【POJ3525】Most Distant Point from the Sea(半平面交+二分+直线平移)
  7. 语言纸对折的厚度编写代码_分享几款由“Python”语言编写的“有趣、恶搞、好玩”的程序代码...
  8. 关于python随机抽取各类型不重复值的思考(sample与randint的区别)
  9. android程序设计背景,android – 以可编程方式设置drawable作为背景
  10. 翻译: 3.2. 从零开始实现线性回归 深入神经网络 pytorch