• 面向对象三大特性之继承


    面向对象的三大特性之继承

    1. 什么是继承

      1. 继承是一种创建新类的方式,新建的类可以继承一个或者多个父类(python支持多继承),父类又可以称为基类又或超类,新建的类称为派生类或者子类.

      2. 子类会'遗传'父类的属性(特征和技能),从而解决代码重用的问题

    class Father:  # 父类
        height = tall
        
    class Son(Father):  # 子类,需要将父类传入
        passprint(Son.height)  #子类直接调用的父类中的属性
    1. 继承与抽象

      • 继承描述的是子类与父类之间的关系,是子类可以用父类中所有属性的方式,所以要对父类进行抽取,不能出现子类不应该有的属性,即抽象

      • 抽象是一种概念性的描述方式,表达的是抽取子类中共同的相似点,新建出一个公共父类.抽象的主要的作用是划分类别(达到隔离关注点,降低复杂度的目的)

      • 所以在编程中与要先分析公共属性抽象后,再继承建立子类

    2. 派生

      • 派生类 : 子类中除有父类中公用的属性外,还应该有自己独特的属性,这种含有自己独特属性的子类被称之为派生类

      • 注意:一旦重新定义了自己的属性且与父类重名,那么调用重定义属性时,就以自己为准.

        即子类中出现了与父类重复的名字,称之为覆盖, 子类出现了与父类不同的名字 称之为派生

       

    3. 子类中调用父类中的方法

      方法一: 指名道姓,即父类名.父类方法()

      方法二:super() 表示创建一个特殊的对象 用于调用父类的方法

      !--了解:在python2中super的使用方式有所不同,需要传入当前类和当前对象--

      # 方法一:指名道姓
      class Human:
      ​
          def __init__(self, name, age, sex):
              self.name = name
              self.age = age
              self.sex = sex
              print(self)
      ​
          def sayhello(self):
              print('hello 我是%s 今年%s岁 性别:%s' % (self.name, self.age, self.sex))
      ​
      ​
      class Student(Human):
          def __init__(self, name, age, sex, number):
              Human.__init__(name, age, sex)
              self.number = number
      ​
          def sayhello(self):
              print('heeeello...')
              Human.sayhello(self)
      ​
      ​
      stu1 = Student('JASSON', 18, 'Male', '123')
      stu1.sayhello()
      ​
      # 输出结果
      heeeello...
      hello 我是JASSON 今年18岁 性别:Male
      ​
      ​
      ​
      # 方法二:super()
      ​
      ...
      class Student(Human):
          def __init__(self, name, age, sex, number):
          # 在python中super()等同于super(Human,self),而super(Human,self)就相当于实例本身
              super().__init__(self, name, age, sex)
              self.number = number
      ​
          def sayhello(self):
              print('heeeello...')
              Human.sayhello(self)
      ​
      # 输出结果
      heeeello...
      hello 我是JASSON 今年18岁 性别:Male
          
          
          
          
      注意:
          当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,
      那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前
      的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表) ​
    4. 存在继承关系后的属性/方法查找

      • 优先查找对象,对象中没有就查找类,类中没有就查找父类,知道不存在父类时都没找到则报错.

      • (了解内容)存在多个父类时的属性查找顺序:

        1. 第一种情况:

          按照定义中传入父类的先后顺序查找

          1.          

        1. 第二种情况:

          1. 存在父类不存在共同父类时(树状结构):深度优先,按照传入父类的顺序查到底,如果没有则查找下一条线,直到查到或查不到报错

            1.                             

          2. 存在的父类存在共同父类时(菱形结构):广度优先,先按照传入父类的顺序查,止步于最后的公共父类,直到所有对象的父类查找完毕后最后查找公共父类.

            1.       

          3. 菱形结构与树状结构的组合(混合结构):将菱形结构整体看做树状结构的一种,其内部仍然以菱形结构查找,查找完毕后进行树状结构.

            1.       

    5. 经典类与新式类

      • 新式类:所有直接继承或者间接继承object的类 都是新式类

        object 称之为根类,意思是所有类都源自与object类

        这么设计的目的:object提供了一些常用的基础操作

      • 注意:

        • python 3中默认所有类都是新式类

        • python 2中默认是经典类(不会自动继承object)

    6. mro 

      • 子类名.mro ():表示属性的查找顺序列表,属性查找就是按照该列表来查找的

    """
    super访问父类内容时 按照mro列表属性查找
    """
    ​
    ​
    class S:
        def f1(self):
            print("s f1")
    ​
    ​
    class A(S):
        pass
    ​
    ​
    class B(S):
        def f1(self):
            print("b f1")
    ​
        pass
    ​
    ​
    class C(A, B):
        def f2(self):
            print("c f2")
            super().f1()
    ​
    ​
    print(C.mro())
    ​
    ​
    # 输出结果 (从左到右即为查找顺序)
    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.S'>, <class 'object'>]
    ​

     

     

  • 相关阅读:
    vim配置
    git rebase
    mongodb的docker-compose.yml
    Nginx配置BrowserRouter跟随react-router
    Flux Architecture & Redux Data Flow & redux & react-redux PPT
    from acwing 从算法数量推算算法复杂度
    evalRPN 逆波兰算术
    二分区间
    Flex布局
    Treap 模板
  • 原文地址:https://www.cnblogs.com/liusijun113/p/10121376.html
Copyright © 2020-2023  润新知