zoukankan      html  css  js  c++  java
  • 面向对象(二)——继承

    继承

    一、什么是继承

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

    二、继承的特点

    1.继承描述的是事物的遗传关系,子类可以重用父类的属性

    2.在Python中支持一个子类继承多个父类

    3.Python类分为两种:新式类、经典类

      (1)新式类:继承object的类,以及该类的子类。

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

     在Python3中默认继承object类,所以Python3中都是新式类;在Python2中要继承object类必须手动继承,所以只有Python中才分新式类和经典类

    三、单继承和多继承

    class Parent1():
        a = 3
    
    class Parent2():
       a = 3
    
    class Sub1(Parent1):         # 单继承,父类是Parent1,子类是Sub1
        a = 2
        pass
    
    
    class Sub2(Parent1,Parent2):       # 多继承,父类是Parent1,Parent2,子类是Sub1
        a = 2
        pass

    四、查看继承

    利用__bases__方法可以查看子类的父类,只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
    
    class Parent1():
        pass
    
    class Sub1(Parent1):
        pass
    
    print(Sub1.__bases__)

    五、继承的作用

    继承解决的是类与类之间的代码冗余问题,一定是一个类是另外一个类的子类

    六、子类重用父类中的方法(派生)

    1、派生:在子类中定义自己的属性,如果与父类的属性重名,那以自己的为准

    2、在子类派生出的新方法中重用父类功能的方式一:指名道姓地访问父类中的函数

      Foo.__init__(self,name,age)     不能自动传值,有几个参数就传几个

    (1)该方式与继承无关

    (2)没有自动传值的效果

     1 class People():
     2     def __init__(self, name, age, sex):
     3         self.name = name
     4         self.age = age
     5         self.sex = sex
     6 
     7 
     8 class Student(People):
     9     def __init__(self, name, age, sex, score=0):
    10         # 方式一 调用父类中的__init__函数
    11         People.__init__(self, name, age, sex)
    12         self.score = score
    13 
    14     def choose(self):
    15         print('%s choosing course' % self)
    16 
    17 
    18 class Teacher(People):
    19     def score(self, stu, score):
    20         stu.score = score
    21 
    22 
    23 stu = Student('张三', 12, 'male')
    24 print(stu.__dict__)      # __dict__可以查看对象的名称空间中的名字
    方式一

    3、在子类派生出的新方法中重用父类功能的方式二:super(),只能在子类中用

      super().__init__(name,age)    自动传值

    (1)在python2中:super(自己的类名,自己的对象)

      在python3:super()    

      调用super()会得到一个特殊的对象,该特殊的对象是专门用来引用父类中的属性的,!!!完全参照mro列表!!!

    (2)super()注意点:

      a. 该方式与继承严格依赖于继承的mro列表,类名.mro()      ===>  不管有没有继承关系,super()都是根据mro往后查找
      b. 访问是绑定方法,有自动传值的效果

     1 class People():
     2     def __init__(self, name, age, sex):
     3         self.name = name
     4         self.age = age
     5         self.sex = sex
     6 
     7 
     8 class Student(People):
     9     def __init__(self, name, age, sex, score=0):
    10         super().__init__(name,age,sex)
    11         self.score = score
    12 
    13     def choose(self):
    14         print('%s choosing course' % self)
    15 
    16 
    17 class Teacher(People):
    18     def score(self, stu, score):
    19         stu.score = score
    20 
    21 
    22 stu = Student('张三', 12, 'male')
    23 print(stu.__dict__)  # 查看对象的名称空间
    方式二

    七、继承背景下的属性查找

    1、单继承背景下的属性查找

    单继承背景下属性查找顺序:对象的名称空间------>对象的类的名称空间------->父类的名称空间

     1 class Foo:
     2      x=333
     3      pass
     4 
     5 class Bar(Foo):
     6 #     x=222
     7      pass
     8 
     9 obj=Bar()
    10 # obj.x=111
    11 print(obj.x)   # 333
    单继承背景下的属性查找

    2、多继承背景下的属性查找

    多继承背景下属性查找的顺序:对象的名称空间------>对象的类的名称空间-------->按照从左往右的顺序一个一个的分支找下去

     1 # 查找顺序是 obj-->A-->B-->E-->C-->F-->I-->D-->H
     2 
     3 #第四层
     4 class I:
     5     # x='I'
     6     pass
     7 
     8 #第三层
     9 
    10 class E:
    11     # x='E'
    12     pass
    13 
    14 class F(I):
    15     # x='F'
    16     pass
    17 
    18 class H:
    19     x='H'
    20 
    21 # 第二层
    22 class B(E):
    23     # x='B'
    24     pass
    25 
    26 class C(F):
    27     # x='C'
    28     pass
    29 
    30 class D(H):
    31     # x='D'
    32     pass
    33 
    34 #第一层
    35 class A(B,C,D):
    36     # x='A'
    37     pass
    38 
    39 obj=A()
    40 # obj.x=111
    41 print(obj.x)
    多继承背景下属性查找

     八、继承顺序

    1、在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如A(B,C,D)

    2、如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

         下图中的继承关系,继承顺序就是A-->B-->E-->G-->C-->F-->D

    3、如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先

    (1)新式类(继承object的类): 广度优先查找,从左往右一个分支一个分支的查找,在最后一个分支才去查找顶级类

        下图为新式类,继承顺序为:A-->B-->E-->C-->F-->D-->G-->object


    (2)经典类(不继承object的类) : 深度优先查找,从左往右一个分支一个分支的查找,在第一个分支就查找顶级类

       下图为经典类,查找顺序为:A-->B-->E-->G-->C-->F-->D

  • 相关阅读:
    redis主从模式
    深入理解BigDecimal
    double使用BigDecimal进行计算出现精确度问题
    代理IP爬取和验证(快代理&西刺代理)
    Jsoup-简单爬取知乎推荐页面(附:get_agent())
    Jsoup-基础练习
    取数据超过内存限制的问题-解决方案(sample,takeSample,filter)
    说出你的故事:你为什么学爬虫
    hadoop第一次面到hr(品友互动)
    MapReduce本地运行模式wordcount实例(附:MapReduce原理简析)
  • 原文地址:https://www.cnblogs.com/linagcheng/p/9505801.html
Copyright © 2011-2022 走看看