zoukankan      html  css  js  c++  java
  • python学习 day20 (3月27日)----(单继承多继承c3算法)

     继承

        提高代码的重用性,减少了代码的冗余
      这两个写法是一样的
    
      Wa('青蛙').walk()    #青蛙 can walk
      wa = Wa('青蛙')
      wa.walk()           #青蛙 can walk  
    View Code
    1.单继承
    麻烦的写法(为什么要有单继承)
      如果多个类相似的情况下(每个都写一遍有大量重复 浪费麻烦)
    class Tiger(object):
        def __init__(self,name):
            self.name = name
        def walk(self):
            print('%s can walk'%self.name)
        def swim(self):
            print('%s can swim'%self.name)
    Tiger('老虎').walk()
    class Swan(object):
        def __init__(self,name):
            self.name = name
        def walk(self):
            print('%s can walk'%self.name)
        def fly(self):
            print('%s can fly'%self.name)
    Swan('鹦鹉').fly()
    class Wa(object):
        def __init__(self,name):
            self.name = name
        def walk(self):
            print('%s can walk'%self.name)
        def swim(self):
            print('%s can swim' % self.name)
    Wa('青蛙').walk()    #青蛙 can walk
    wa = Wa('青蛙')
    wa.walk()           #青蛙 can walk
    class Er(object):
        def __init__(self,name):
            self.name = name
        def walk(self):
            print('%s can walk'%self.name)
        def swim(self):
            print('%s can swim' % self.name)
        def fly(self):
            print('%s can fly'%self.name)
    
    # Er('天鹅').swim()
    Er('天鹅').fly()

    继承

      创建一个父类

      子类用父类的属性和方法 因为都差不多

      子类也可以新建自己特殊的属性和方法,通过super().__init__(相同元素) 和 父类名.__init__(self,相同元素)

      方法的话  自己新建 不必返回父类

    class Animal(object):
        def __init__(self,name,kind):
            self.name = name
            self.kind = kind            #多了不是很好
        def walk(self):
            print('%s can walk'%self.name)
        def swim(self):
            print('%s can swim' % self.name)
        def fly(self):                  #可以有任意个
            print('%s can fly'%self.name)
    class Tiger(Animal):pass
    class Bird(Animal):
        def __init__(self,name,kind,eyes_color):  #小心 元素必须与父类相同
            # super().__init__(name,kind)
            # super(Bird,self).__init__(name,kind)  #注意 括号前面的元素是子类 当前类  告诉父类
            Animal.__init__(self,name,kind)     #注意 没有括号
            self.eyes_color = eyes_color  #自己的属性 自己赋值
        def say(self):
            print("%s can say like people"%self.name)
    laohu = Tiger('老虎','')      # 实参与形参一一对应  即动物的属性此对象都有 也麻烦
    print(laohu.walk(),laohu.fly(),laohu.name)        # 父类的方法和属性都可以用了 继承
    yingwu = Bird('鹦鹉','','blue')      # 最好变量名 有意义  不是 abcd 。。。
    print(yingwu.fly(),yingwu.eyes_color,yingwu.say())

     多继承

    引子:

    各种动物,每一种动物都是一个类
    青蛙、天鹅、老虎、鹦鹉
    青蛙 :走,游泳
    天鹅 :走,游泳,飞
    老虎 :走,游泳
    鹦鹉 :走,飞,说话
    class FlyAnimal:
        def fly(self):pass
    class SwimAnimal:
        def swim(self):pass
        def eat():pass
    class WalkAnimal:
        def walk(self):pass
        def eat():pass
    
    class Frog(SwimAnimal,WalkAnimal): pass
    class Tiger(SwimAnimal,WalkAnimal):pass
    class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass
    class Parrot(FlyAnimal,WalkAnimal):
        def talk(self):
            pass
    View Code

    class Frog(SwimAnimal,WalkAnimal): pass
    class Tiger(SwimAnimal,WalkAnimal):pass
    class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass
    class Parrot(FlyAnimal,WalkAnimal):
    def talk(self):
      pass

    多继承 是python语言中特有的继承方式
    java语言中不支持多继承的,C# 也不支持多继承
    C++支持多继承
    c c++ c# java
    
    多继承和单继承是一样的
        如果对象使用名字
        是子类中有的,那么一定用子类的
        子类没有,可以到多个父类中去寻找
    如果多个和父类都有,那么用谁的
     如果父类子类都想用,super(),父类名.方法名
    算法:
    1钻石继承问题

    代码实现:
    钻石继承问题
    class A(object):
        def func(self):
            print('a')
    class B(A):
        # def func(self):
        #     print('b')
    class C(A):
        # def func(self):
        #     print('c')
    class D(B,C):
        # def func(self):
        #     print('d')
    d = D()
    d.func()
    View Code

      逐个隐藏 函数 来查看调用顺序

     

    # super().func() 左想
    class A(object):
        def func(self):
            print('a',end='')
    
    class B(A):
        pass
        def func(self):
            super().func()
            print('b',end='')
    
    class C(A):
        pass
        def func(self):
            super().func()
            print('c',end='')
    
    class D(B,C):
        pass
        def func(self):
            super().func()
            print('d',end='')
    
    b = B()
    b.func()
    print()
    d = D()
    d.func()
    # 在多继承中,super就只和mro顺序有关系,和父类子类没有关系了
    View Code
    2乌龟继承顺序

    代码实现:
    乌龟继承问题
    class A(object):
        def func(self):
            print('a')
    
    class B(A):
        pass
        # def func(self):
        #     print('b')
    
    class C(A):
        pass
        # def func(self):
        #     print('c')
    class D(B):
        pass
        # def func(self):
        #     print('d')
    class E(C):
        pass
        # def func(self):
        #     print('e')
    
    class F(D,E):
        pass
        # def func(self):
        #     print('f')
    f = F()
    f.func()
    View Code

     过程实现:

    # C3算法
    # A= [AO]
    # B = B ,B节点的父类对应的顺序
    # B = B ,A节点顺序
    # B = B ,[AO]
    # 提取第一个点
        # 如果从左到右第一个类,
        # 在后面的继承顺序中也是第一个,或者不再出现在后面的继承顺序中
        # 那么就可以把这个点提取出来,作为继承顺序中的第一个类
    # B = [AO]
    # BA = [O]
    # B这个节点的继承顺序 :[BAO]
    # C = C,[AO]
    # C = [AO]
    # CA = [O]
    # C这个节点的继承顺序 :[CAO]
    # l(D) = D + [BAO]
    # D = [BAO]
    # [DBAO]
    
    # l(E) = E + [CAO]
    # [ECAO]
    
    # L[F] = F,[BAO],[ECAO]
    # [F] = [DBAO],[ECAO]
    # [FD] = [BAO],[ECAO]
    # [FDB] = [AO],[ECAO]
    # [FDB] = [AO],[ECAO]
    # [FDBE] = [AO],[CAO]
    # [FDBEC] = [AO],[AO]
    # [FDBECA] = [O],[O]
    # [FDBECAO]
    View Code
    广度优先
        C3算法
    99%的情况都可以用眼睛看出来
    但是仍然有1%的情况是看不出来的
    
    C3算法是怎么计算的
    C3算法代码实现
    class A(object):
        def func(self):
            print('a')
    
    class B(A):
        pass
        def func(self):
            print('b')
    
    class C(A):
        pass
        def func(self):
            print('c')
    class F:
        pass
        def func(self):
            print('f')
    
    class D(A,F):
        pass
        # def func(self):
        #     print('d')
    class E(B,C,F):
        pass
        def func(self):
            print('e')
    class G(C,D):
        pass
        def func(self):
            print('g')
    class H(E,G):
        pass
        def func(self):
            print('h')
    print(H.mro())   # 就是帮助我们来展示c3算法的继承顺序
    View Code

     在python2.7中

      主动继承object才是新式类,默认是经典类
    # coding:utf-8
    # 新式类 继承object
    # 经典类 只在py2.x中有 默认不继承object
    # 多继承
    # 遵循的是深度优先
    class A:pass
        # def func(self):
        #     print('a')
    class B(A):
        pass
        # def func(self):
        #     print('b')
    class C(A):
        pass
        def func(self):
            print('c')
    class D(B,C):pass
        # def func(self):
        #     print('d')
    d = D()
    d.func()
    View Code

    继承总结

    单继承
    子类有的就用子类的
    没有的就用父类的
    如果父类子类都想用,super(),父类名.方法名
    多继承
    新式类 :
    继承object
    py2 要主动继承object才是新式类,默认是经典类
    python2 必须 super(现在类,self) 传给父类(object)
    遵循的是广度优先算法,C3算法
    有super()的,super遵循mro顺序的
    有mro()方法

    经典类 :
    不继承object
    多个类之间去寻找方法的时候遵循深度优先
    没有super方法
    也没有mro
    只在python2 中存在

     人狗大战:

      继承写法

    class Animal(object):
        def __init__(self,name,blood,ad):
            self.name = name
            self.hp = blood
            self.ad = ad
    class Dog(Animal):
        def __init__(self,name,blood,ad,kind):
            super().__init__(name,blood,ad)
            self.kind = kind
    
        def bite(self,person):
            person.hp -= self.ad
            print('%s攻击了%s,%s掉了%s点血' % (self.name, person.name, person.name, self.ad))
    
    class Person(Animal):
        def __init__(self,name,hp,ad,sex):
            super().__init__(name,hp,ad)
            self.sex = sex
    
        def fight(self,dog):
            dog.hp -= self.ad
            print('%s攻击了%s,%s掉了%s点血'%(self.name,dog.name,dog.name,self.ad))
    
    hei = Dog('小黑',300,20,'哈士奇')
    alex = Person('alex',20,1,'不详')
    alex.fight(hei)
    print(hei.hp)
    hei.bite(alex)
    print(alex.hp)
    
    
    
    # 抽象
    # 继承
    
    # 组合 :什么有什么
    # 继承 :什么是什么的关系
        # 先想描述的对象
        # 先写出对象所对应的类
        # 发现多个类之间有相同的代码
        # 把相同的代码提取出来,搞成一个父类
    
    # 先抽象,再继承
    # 对象 -->类 -->基类
    # 基类 -继承-> 子类 -实例化-> 对象
    View Code


  • 相关阅读:
    硬盘参数你都懂吗?(上)-从案例引发的讨论
    Python 面试题(下)
    Python 面试题(上)
    DNS 原理入门
    从硬盘设计思想到RAID改良之道
    (转)短信vs.推送通知vs.电子邮件:app什么时候该用哪种方式来通知用户?
    (转)移动端主动推送消息原理
    (转)OpenFire源码学习之十七:HTTP Service插件
    (转)openfire插件开发(二) 基于web的插件开发
    (转)openfire插件开发(一)
  • 原文地址:https://www.cnblogs.com/Doner/p/10605655.html
Copyright © 2011-2022 走看看