• 面向对向


    一、 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,新建的类可称为子类或派生类,父类又可称为基类或超类

    class ParentClass1:  #定义父类

      pass

    class ParentClass2:  #定义父类

      pass

    class SubClass1(ParentClass1):   #单继承

      pass

    class SubClass(ParentClass1,ParentClass2): #多继承

      pass

    通过类的内置属性__bases__可以查看类继承的所有父类

    >>> SubClass2.__bases__

    二、在python2中有经典类与新式类之分

    新式类:继承了object类的子类,以及该子类的子类子子类。

    经典:没有继承object类的子类,以及该子类的子类子子类。

    在python3中没有继承任何类,那么会默认继承object类,所以 python3中所有的类都是新式类

    三、python的多继承

      优点:子类可以同时遗传多个父类的属生,最大限度地重用代码

      缺点:

        1、违背人的思维习惯:继承表达的是一种什么‘是'什么的关系

        2、代码可读性会变差

        3、不建议使用多继承,有可能会引发可恶的菱形问题 ,扩展性变差,

          如果真的涉及到一个子类不可避免地要重用多个父类的属性,应该使用Mixins

    为何要用继承:用来解决类与类之间代码冗余问题 

    三、如何实现继承

    类与类之间存在冗余问题

    class OldboyPeople:

      school = 'OLDBOY'

      def __init__(self,name,age,sex):

        self.name = name

        self.age = age

        self.sex = sex

    class Student(OldboyPeople):

      def choose_course(self):

        print('学生%s 正在选课'% self.name)

    class Teacher(OldboyPeople):

      def __init__(self,name,age,sex,salary,level):

        OldboyPeople.__init__(self,name,age,sex)  #指名道姓地跟父类去要

        self.salary = salary

        self.level = level 

      def score(self):

        print('老师 %s正在给学生打分‘%self.name)

    tea_obj = Teacher('egon',18,'male',3000,10)

    print(tea_obj.__dict__)

    tea_obj.score()

    四、属性查找

    有了继承关系,对象在查找属性时,先从对象自己的__dict__中找,如果没有则去子类上找,然后再去父类中找

    class Foo:

      def f1(self):

        print('Foo.f1')

      def f2(self):

        print('Foo.f2')

        self.f1()

    class Bar(Foo):

      def f1(self):

        print('Foo.f1')

    b = Bar()

    b.f2()

    Foo.f2

    Foo.f1

    五、菱形问题

    大多数面向对象语言都不支持多继承,而在python中,一个子类是可以同时继承多个父类的,这固然可以带来一个子类可以对多个不同父类加以重用的好处,但也有可能引发著名的Diarmond problem菱形问题(或称钻石问题 )

    菱形期实就是对下面这种继承结构的形象比喻。

    这种继承结构下导致的问题称之为菱形问题 :如果A中有个方法,B和或C都重写了该方法,而D没有重写它,那么D继承的是哪个版本的方法:B的还是C的?

    继承原理

    python到底是如何实现继承的呢?对于你定义的每一个类,python都会计算出一个方法解析顺序(MRO)

    python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不支深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

    1、子类会先于父类被检查

    2、多个父类会根据它们在列表中的顺序被检查

    3、如果对下一个类存在两个合法的选择,选择第一个父类

    由对象发起的属生查找,会从对象自身的属性里检索,没有则会按照对象的类.mro()规定的顺序依次找下去

    由类发起的属性查找,会按照当前类.mro()规定的顺序依次找下去

    五、深度优先和广度优先

    参照下述代码,多继承结构为非菱形结构,此时,会按照先找B这一条分支,然后再找C这条分支,最后找D这一条分支的顺序直到找到我们想要的属性

    如果继承关系为菱形结构,那么经典类与新式类会有不同mro,分别对应属性的两种查找方式:

    深度优先和广度优先

    查找顺序为:obj>A>B>E>C>F>D>G>object

  • 相关阅读:
    如何使得事务使用同一个连接对象Connection呢?
    快速使用上咱的ideal的快捷键小技巧
    委托模式的理解:
    克隆、深拷贝与浅拷贝区别
    mysql存储过程与事务
    sql异常处理以及sql异常处理优先级
    Mysql 遇到神奇的“本次本客户端效现象”,数据库并未被改变 + 神奇“卡顿现象”
    网络传输时既有管道流(PipedInputStream 与 PipedOutStream)又有序列化对象、反序列化对象(ObjectOutputStream与 ObjectInputStream),还有在集合中、流中都有的身影的Properties究竟是何方神物?我们该怎么选择呢?
    数据库设计的三大范式
    实体类(VO,DO,DTO,PO)的划分
  • 原文地址:https://www.cnblogs.com/acnjanna2019/p/12669044.html
Copyright © 2020-2023  润新知