• 第五章---面向对象---1.继承/2.派生/3.继承的实现原理/4.在子类中重用父类的方法和属性


    1.继承:指的是类与类之间的关系,是一种什么是什么的关系,继承的功能是解决代码的重用问题,继承是一种创建新类的方式
    python 中新建的类可以继承一个或多个父类(基类或超类)
    新建的类称为派生类或子类

    对象之间相似的特征-------类
    类之间相似的特征 ---- 父类

    继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

     1 class ParentClass1:
     2     pass
     3 
     4 class ParentClass2:
     5     pass
     6 
     7 class SubClass1(ParentClass1):
     8     pass
     9 
    10 class SubClass2(ParentClass1,ParentClass2):
    11     pass
    12 
    13 # print(SubClass1.__bases__)
    14 # print(SubClass2.__bases__)
    15 #
    16 # # (<class '__main__.ParentClass1'>,)
    17 # # (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
    18 
    19 
    20 class Hero:
    21     def __init__(self,name,attack,life_value):
    22         self.name = name
    23         self.attack = attack
    24         self.life_value = life_value
    25 
    26     def attack_other(self,enemy):
    27         enemy.life_value -= self.attack
    28         if enemy.life_value <= 0:
    29             print('%s 没有血量,宣布死亡!'% enemy.name)
    30         else:
    31             print('%s血量剩余%s'% (enemy.name,enemy.life_value))
    32 class HeroDog(Hero):
    33     pass
    34 
    35 class HeroPig(Hero):
    36     pass
    37 
    38 hero_d = HeroDog('Dog',10,100)
    39 hero_p = HeroPig('pig',20,100)
    40 
    41 # hero_d.attack_other(hero_p)
    42 
    43 继承属性查找小练习:
    44 
    45 练习一:
    46 class Foo:
    47     def f1(self):
    48         print('from Foo.f1')
    49     def f2(self):
    50         print('from Foo.f2')
    51         self.f1()
    52 
    53 class Bar(Foo):
    54     def f2(self):
    55         print('from Bar.f2')
    56 
    57 b1 = Bar()
    58 b1.f2()
    59 # from Bar.f2
    60 b1首先在自己这个对象中找f2(),找不到然后去自己所在的类Bar中去找,找到了输出结果
    61 
    62 练习二:
    63 class Foo:
    64     def f1(self):
    65         print('from Foo.f1')
    66     def f2(self):
    67         print('from Foo.f2')
    68         self.f1() # b.f1()
    69 
    70 class Bar(Foo):
    71     def f1(self):
    72         print('from Bar.f1')
    73 
    74 b1 = Bar()
    75 b1.f2()
    76 # from Foo.f2
    77 # from Bar.f1
    78 # b1首先在自己这个对象中找f2(),找不到然后去自己所在的类Bar中去找,
    79 # 仍然找不到就会去Bar的父类Foo中去找,找到了,首先打印的是'from Foo.f2',
    80 # 然后会执行self.f1(),由于这个self就是对象b1,所以会继续前面的寻找方式,
    81 # 先去自己本身的对象中找,找不到去所在的类,找不到在去类所在的父类!

    2.派生
    :子类可以添加自己的 新属性 数据属性 函数属性
    查找顺序:1.对象本身--》2.对象所在的类里面找--》3.父类里面找
     1 class Hero:
     2     def __init__(self,name,attack,life_value):
     3         self.name = name
     4         self.attack = attack
     5         self.life_value = life_value
     6 
     7     def attack_other(self,enemy):
     8         enemy.life_value -= self.attack
     9         if enemy.life_value <= 0:
    10             print('%s 没有血量,宣布死亡!'% enemy.name)
    11         else:
    12             print('%s血量剩余%s'% (enemy.name,enemy.life_value))
    13 
    14 class HeroDog(Hero):
    15     camp = 'Dog_camp'
    16     def attack_other(self,enemy):
    17         print('from HeroDog class')
    18 
    19 class HeroPig(Hero):
    20     camp = 'Pig_camp'
    21 
    22 hero_d = HeroDog('Dog',10,100)
    23 hero_p = HeroPig('pig',20,100)
    24 hero_d.attack_other(hero_p)

    3.继承的实现原理:python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表

    例如:
    >> F.mro() #等同于F.__mro__
    [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
    0.对象本身优先于子类
    1.子类会先于父类被检查
    2.多个父类会根据它们在列表中的顺序被检查
    3.如果对下一个类存在两个合法的选择,选择第一个父类

    在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如果继承了多个父类,那么属性的查找方式有两种,
    分别是:深度优先和广度优先 (本质按列表顺序来) --》只是一种排序的不同方式

    python中类分为两种:1.新式类 2.经典类 (py2中)
    1.新式类 (py3 --> 只有新式类)

     1 # 在python2中-》 经典类:没有继承object的类,以及他的子类都称之为经典类
     2 # class Foo:
     3 #     pass
     4 #
     5 # class Bar(Foo):
     6 #     pass
     7 
     8 # 在python2中-》 新式类:继承了object的类,以及他的子类都称之为经典类
     9 # class Foo(object):
    10 #     pass
    11 #
    12 # class Bar(Foo):
    13 #     pass
    14 
    15 # 在python3中-》 新式类:一个类没有继承object类,默认就继承object
    16 # class Foo:
    17 #     pass
    18 # print(Foo.__bases__)
    19 
    20 
    21 # 验证多继承情况下的属性查找  -- # F D B X E C A  新式类 --》 广度优先
    22 class A(object):
    23     # def test(self):
    24     #     print('from A')
    25     pass
    26 
    27 class B(A):
    28     # def test(self):
    29     #     print('from B')
    30     pass
    31 
    32 class C(A):
    33     # def test(self):
    34     #     print('from C')
    35     pass
    36 
    37 class D(B):
    38     # def test(self):
    39     #     print('from D')
    40     pass
    41 
    42 class E(C):
    43     # def test(self):
    44     #     print('from E')
    45     pass
    46 
    47 class F(D,E):
    48     # def test(self):
    49     #     print('from F')
    50     pass
    51 f1=F()
    52 f1.test()
    53 print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
    54 # (<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
    55 
    56 #新式类继承顺序:F->D->B->E->C->A
    57 #经典类继承顺序:F->D->B->A->E->C
    58 #python3中统一都是新式类
    59 #pyhon2中才分新式类与经典类

     4.在子类中重用父类的方法和属性

    在子类派生出的新的方法中重用父类的方法:有两种实现方式:
    方式一:指名道姓(不依赖继承)
    Hero.attack_other(self,enemy) # 指名道姓 不依赖继承
    Hero.__init__(self,name,attack,life_value) # 指名道姓 不依赖继承

    方式二:super() (依赖继承) super() 会从对象的(MRO)列表中找
    super(Garen,self).attack_other(enemy) # 依赖继承
    super(Garen,self).__init__(name,attack,life_value) # 依赖继承 py2 写法
    super().__init__(name,attack,life_value) # py3 写法
      1 # 方式一:指名道姓
      2 # class Hero:
      3 #     def __init__(self,name,attack,life_value):
      4 #         self.name = name
      5 #         self.attack = attack
      6 #         self.life_value = life_value
      7 #
      8 #     def attack_other(self,enemy):
      9 #         enemy.life_value -= self.attack
     10 #         if enemy.life_value <= 0:
     11 #             print('%s 没有血量,宣布死亡!'% enemy.name)
     12 #         else:
     13 #             print('%s血量剩余%s'% (enemy.name,enemy.life_value))
     14 #
     15 # class HeroDog(Hero):
     16 #     camp = 'Dog_camp'
     17 #     def attack_other(self,enemy):
     18 #         Hero.attack_other(self,enemy) # 指名道姓方法,不依赖继承
     19 #         print('from HeroDog class')
     20 #
     21 # class HeroPig(Hero):
     22 #     camp = 'Pig_camp'
     23 #
     24 # hero_d = HeroDog('Dog',10,100)
     25 # hero_p = HeroPig('pig',20,100)
     26 # hero_d.attack_other(hero_p)
     27 
     28 
     29 # 方式一:指名道姓
     30 # class Hero:
     31 #     def __init__(self, name, attack, life_value):
     32 #         self.name = name
     33 #         self.attack = attack
     34 #         self.life_value = life_value
     35 #
     36 #     def attack_other(self, enemy):
     37 #         enemy.life_value -= self.attack
     38 #         if enemy.life_value <= 0:
     39 #             print('%s 没有血量,宣布死亡!' % enemy.name)
     40 #         else:
     41 #             print('%s血量剩余%s' % (enemy.name, enemy.life_value))
     42 #
     43 #
     44 # class HeroDog(Hero):
     45 #     camp = 'Dog_camp'
     46 #
     47 #     def __init__(self,name,attack,life_value,weapon):
     48 #         # self.name = name
     49 #         # self.attack = attack
     50 #         # self.life_value = life_value
     51 #         Hero.__init__(self,name,attack,life_value) # 指名道姓方法
     52 #
     53 #         self.weapon = weapon
     54 #
     55 #     def attack_other(self, enemy):
     56 #         Hero.attack_other(self, enemy)  # 指名道姓方法,不依赖继承
     57 #         print('from HeroDog class')
     58 #
     59 # hero_d = HeroDog('Dog', 10, 100,'大刀')
     60 # print(hero_d.__dict__)
     61 
     62 
     63 # 方式二:super() (依赖继承)
     64 # class Hero:
     65 #     def __init__(self,name,attack,life_value):
     66 #         self.name = name
     67 #         self.attack = attack
     68 #         self.life_value = life_value
     69 #
     70 #     def attack_other(self,enemy):
     71 #         enemy.life_value -= self.attack
     72 #         if enemy.life_value <= 0:
     73 #             print('%s 没有血量,宣布死亡!'% enemy.name)
     74 #         else:
     75 #             print('%s血量剩余%s'% (enemy.name,enemy.life_value))
     76 #
     77 # class HeroDog(Hero):
     78 #     camp = 'Dog_camp'
     79 #     def attack_other(self,enemy):
     80 #         super(HeroDog,self).attack_other(enemy) # 依赖继承
     81 #         # super(HeroDog,self) 这就是父类的对象
     82 #         print('from HeroDog class')
     83 #
     84 # class HeroPig(Hero):
     85 #     camp = 'Pig_camp'
     86 #
     87 # hero_d = HeroDog('Dog',10,100)
     88 # hero_p = HeroPig('pig',20,100)
     89 # hero_d.attack_other(hero_p)
     90 
     91 
     92 # 方式二:super() (依赖继承)
     93 # class Hero:
     94 #     def __init__(self, name, attack, life_value):
     95 #         self.name = name
     96 #         self.attack = attack
     97 #         self.life_value = life_value
     98 #
     99 #     def attack_other(self, enemy):
    100 #         enemy.life_value -= self.attack
    101 #         if enemy.life_value <= 0:
    102 #             print('%s 没有血量,宣布死亡!' % enemy.name)
    103 #         else:
    104 #             print('%s血量剩余%s' % (enemy.name, enemy.life_value))
    105 #
    106 #
    107 # class HeroDog(Hero):
    108 #     camp = 'Dog_camp'
    109 #
    110 #     def __init__(self,name,attack,life_value,weapon):
    111 #         # super(HeroDog,self).__init__(name,attack,life_value)
    112 #         super().__init__(name, attack, life_value) # python可以这样简写
    113 #         self.weapon = weapon
    114 #
    115 #     def attack_other(self, enemy):
    116 #         Hero.attack_other(self, enemy)  # 指名道姓方法,不依赖继承
    117 #         print('from HeroDog class')
    118 #
    119 # hero_d = HeroDog('Dog', 10, 100,'大刀')
    120 # print(hero_d.__dict__)
    121 
    122 #--------------------------------------------------------
    123 # A没有继承B,但是A内super会基于C.mro()继续往后找
    124 class A:
    125     def f1(self):
    126         print('from A')
    127         super().f1()
    128 
    129 class B:
    130     def f1(self):
    131         print('from B')
    132 
    133 class C(A,B):
    134     pass
    135 # print(C.mro())
    136 # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    137 
    138 c = C()
    139 c.f1()
    140 # from A
    141 # from B
  • 相关阅读:
    汉罗塔问题
    有进度条圆周率计算
    turtle库笔记
    OwnCloud建立属于自己私有的云存储网盘
    HTTP 常见请求状态码
    虚拟机部署Kubernetes集群
    常用文件头(16进制)
    配置LAMP环境
    Linux系统日志
    Java的socket通信与操作系统的SocketAPI关系探究
  • 原文地址:https://www.cnblogs.com/mumupa0824/p/8951936.html
Copyright © 2020-2023  润新知