day20

天大地大妈咪最大 提交于 2019-12-01 02:28:24

一、继承

类的继承

  • 面向对象三要素之一,继承Inheritance
  • class Cat(Animal)这种形式就是从父类继承,继承可以让子类从父类获取特征(属性和方法)
  • 在面向对象的世界中,从父类继承,就可以直接拥有父类的属性和方法,这样可以减少代码,多复用,子类可以定义自己的属性和方法

    1、查看继承的特殊属性和方法

  • base : 类的基类
  • based : 类的基类元组
  • mro : 显示方法查找顺序,基类的元组
  • __mro()__方法 : 显示方法查找顺序,基类的元组
  • subclasses() : 类的子类列表

2、继承中的查找顺序

  • 从父类继承,自己没有的就可以到父类中找
  • 私有的都是不可以访问的,但是本质上依然是改了名称放在这个属性所在类的_dict-中
  • 继承时,公有的,子类和实例都可以随意访问,私有成员被隐藏了,子类和实例不可直接访问
  • 当私有变量所在的类内的方法中可以访问这个私有变量
  • 属性查找属性:实例的dict--》类的dict--》父类dict

多继承

  • OCP原则:多继承,少修改;继承的用途:增强基类,实现多

1、多态

  • 在面向对象中,父类,子类通过继承联系在一起,如果可以通过一套方法,就可以实现不同的表现,就是多态
  • 一个类继承自多个类就是多继承,它将具有多个类的特征

2、多继承弊端

  • 多继承很好的模拟了世界,因为事物很少是单一继承,但是舍弃简单,必然引入复杂性带来冲突
  • 如同一个孩纸继承了来自父母双方的特征
  • 多继承的实现会导致编译器设计的复杂度增加,所以现在很多语言也舍弃了类的多继承

3、python多继承实现

  • 多继承带来路径选择问题,究竟继承哪个父类的特征
  • python使用MRO(method resolution order)解决基类搜索顺序问题

4、多继承的缺点

  • 当类很多,继承复杂的情况下,继承路径太多,很难说清楚什么样的继承路径
  • python语法是允许多继承,但是python代码是解释执行,只有执行到的时候才发现错误

5、用装饰器增强

  • 用装饰器增强一个类,把功能给类附加上去,哪个类需要,就装饰它
  • 优点:简单方便,在需要的地方动态增加,直接使用装饰器

二、派生

​ 派生:子类定义自己新的属性,如果与父类同名,以子类自己的为准

在子类派生出的新方法中重用父类的功能:

方式一:指名道姓地调用(与继承没有什么关系)

方式二:super()调用(严格依赖于继承)

super ( ) 的返回值是一个特殊的对象,该对象专门用来调用父类中的属性,super()会严格按照mro列表从当前查找到的位置继续往后查找

经典类和新式类:

1、新式类: 继承object的类,以及该类的子类,都是新式类

在python3中,如果一个类没有指定继承的父类,默认就继承object,所以说python3中所有的类都是新式类

2、经典类(只有在python2才区分经典类与新式类):没有继承object的类,以及该类的子类,都是经典类

在多继承背景下的属性查找:

属性查找
obj.x
1、先从obj.__dict__
2、对象的类.__dict__
3、父类.__dict__

如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性
如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先
print(F.__mro__) # F.mro() #只有新式类才有这个属性可以查看线性列表,查看属性查找顺序,经典类没有这个属性

类的组合

  • 组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象
  • 组合的好处:解决类与类之间代码冗余的问题

组合的应用

  • 需求:假如我们需要给学生增添课程属性,但是又不是所有的学生一进学校就有课程属性,课程属性是学生选出来的,也就是说课程需要后期学生们添加进去
  • 实现思路:如果我们直接在学生中添加课程属性,那么学生刚被定义就需要添加课程属性,这就不符合我们的要求,因此我们可以使用组合能让学生未来添加课程属性

菱形继承问题

在Python中子类可以同时继承多个父类,如A(B,C,D)

  • 如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这条分支,最后找D这条分支的顺序直到找到我们想要的属性
  • 如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方式有两种

经典类(了解)

一条路走到黑,深度优先

img

查找顺序:A -> B -> E -> G -> C -> F -> D

新式类

不找到各类最后继承的同一个类,直接去找下一个父类,广度优先

img

查找顺序:A -> B -> E -> C -> F -> D -> G

mro方法

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,如:

print(A.__mro__)  # 在此用python3运行,广度优先
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
for i in A.__mro__:
    print(i)
<class '__main__.A'>
<class '__main__.B'>
<class '__main__.E'>
<class '__main__.C'>
<class '__main__.F'>
<class '__main__.D'>
<class '__main__.G'>
<class 'object'>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!