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

  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/linagcheng/p/9505801.html
Copyright © 2011-2022 走看看