zoukankan      html  css  js  c++  java
  • python==继承===18

    继承        表示的是     什么是什么的关系     例如   狗是动物  

     继承的好处: 

        a,提高了代码的复用性
        b:提高了代码的维护性
        c:让类与类之间产生了关系,是多态的前提

    面向对象的三大特征:    继承   多态   封装

    继承

      class  Animal:

        breath="呼吸"

        def   _ _init_ _(self,name,sex,age):

          self.name=name

          self.sex=sex

          self.age=age

        def  eat(self):

          print(666)

      class  Person( Animal ):

        pass

    p1=Person("haha","女",18)

    初识继承  :  子类 以及子类 实例化对象,   可以访问父类的 任何方法 或变量

      类名可以访问父类中的所有内容

        print( Person.braeth )  ===>  呼吸

        Person . eat (111)  ===>  666

      子类实例化的对象  也可以访问  父类中的  所有内容

        print( p1.breath )====>  呼吸

        p1.eat()   =====>   666

    只执行父类的方法  :  子类中不要定义与父类同名的方法

    只执行子类的方法  :  在子类中创建这个方法   

    若    既要执行子类中的方法   又要执行父类中的方法  有两种方法解决

        class  Animal:

          def  _ _init_ _( self , name , sex, age ) :

            self.name=name

            self.sex=sex

            self.age=age

          def  eat(self):

            print(  "呵呵"  )

        class  Bird(Animal):

          def  _ _init_ _(self,skin)

            self.skin=skin

          def  eat( self ):

    方法一     Aimal . eat(self)     #  调用父类中的方法   

    方法二     super().eat(name,sex,age)   #  

            print(  "哈哈"  )

    b1=Bird("小小鸟", "公", "1" ,"彩色")

    b1.eat()====>   呵呵  哈哈    

     类名 + 方法(所需要的参数)    #  放置到子类方法中    既可以调用  父类中的  eat()方法,  又可以调用  自己类中的eat()方法

                    必须将所有参数传进来,   若要调用  _ _init_ _方法则将  (self, name, sex ,age)  都要传进去

     super().方法名( 除了self , 所有参数)     #  相当于super(本类类名+self),  会自动执行_ _init_ _并将  self  传进来,父类所需要的                                                                            参数也要自己输入传进来

    class  Animal:

          def  _ _init_ _( self , name , sex, age ) :

            self.name=name

            self.sex=sex

            self.age=age

          def  eat(self):

            print(  "呵呵"  )

        class  Bird(Animal):

          def  _ _init_ _(self, name , sex, age ,skin)

    方法一     Aimal . _ _init_ _(self,name,sex,age)     #  调用父类中的方法   

    方法二     super()._ _init_ _(name,sex,age)     #     调用父类中的

            print('111')

            self.skin=skin

          def  eat( self ):

            print(  "哈哈"  )

    b1=Bird("小小鸟", "公", "1" ,"彩色")

    b1.eat()====>   111     { name: 小小鸟  ,  sex : 公   ,  age: 7 , haha:  彩色  }  

      

     继承的进阶 

      继承:  单继承   多继承  

      类:   经典类    新式类 

        新式类:    凡是  继承  object  类的  都是新式类  

            python 3x  中所有的类都是新式类  ,因为 其中 的类都默认继承  object  

        经典类 :  不继承  object  类的  都是  经典类

            在  python 2 中 所有的类 都 默认 不继承 object ,  因此所有的都是  经典类   ,

            但是  , 我们  在它终极父类中,让他继承     父类(object)   就变为了   新式类 

     

      单继承 ,  经典类  类的继承顺序是一样的

         现在自身 类中找  如果没有去父类中找,再没有再去父类中找  

            在任何类中调用的方法, 都要仔细分辨一下  这个self  到底是谁的对象

      多继承  

        新式类   继承顺序  :   遵循  广度优先  (  每个节点 只走一次  , 当走到一个节点是 倒数第二级  的时候 

                           判断  其他路线 是否可以到达终极父类, 

                            若可以就不走,   从头开始   ,走另一条大路...)

            在新式类中  super().func()遵循mro算法  在类的内部不用传子类名和self

              因此  super()执行顺序也是  按照  mro算法的顺序来执行的   ,

                若每个类中都有super()则先确定好函数的mro 算法,然后按照  mro 顺序执行  

        经典类    继承顺序  :   遵循  深度优先   (  一条路 走到头   , 再从头开始  走另一条大路  )

            在经典类中   super(  子类名,self  ).func(除了self  的参数)       子类名和self   必须手动传

            python  2 中没有mro 算法

      对于    新式类   来说     直接   print(  类名 . mro ( )   )     可以直接  查看  类的继承顺序    

      e.g

      class  A:

        def  func(self):              新式类   继承顺序:

          print(" A ")                  A

                                      5

      class  B(A):

        def  func(self):          B(A)              C(A)

          print(" B")                  3          4

                        2

      class  C(A):             D(B)                E(C)

        def  func(self):              

          print(" C ")              1           

                                  F(D,E)

      class  D(B):

        def  func(self):          先执行F(D,E)   ,若没有找     D

          print(" D ")           执行 D(B),    若没有找     B

      class  E(C):              执行 B(A)  ,    A  是终极父类  , 看其他有没有到  A的  如果有 pass 从头开始

        def  func(self):            F(D,F),  D走过了, 找E      

          print(" E ")            E(C)  , 若找不到    找C

      class  F(D,E):              C(A)   ,   若找不到   找A

        def  func(self):

          print(" F ")

    f1=F()

    f1.func()             

    class  A:

        def  func(self):              经典类   继承顺序:

          print(" A ")                  A

                             3         

      class  B(A):

        def  func(self):          B(A)              C(A)

          print(" B")                            5

                        2

      class  C(A):             D(B)                E(C)

        def  func(self):                        

          print(" C ")              1           4  

                                  F(D,E)

      class  D(B):

        def  func(self):          先执行F(D,E)   ,若没有找     D

          print(" D ")           执行 D(B),    若没有找     B

      class  E(C):              执行 B(A)  ,    若没有找A    

        def  func(self):            A若没有  F(D,F),  D走过了, 找E      

          print(" E ")            E(C)  , 若找不到    找C

      class  F(D,E):              

        def  func(self):

          print(" F ")

    f1=F()

    f1.func()

    多继承  继承顺序  C3算法原理   

    A(B,C,D)
    #首先找到A继承的三个类的深度继承顺序,放到一个列表中
    L[B] = [B,D,F,H] #B往上面的继承顺序
    L[C] = [C,E,G,H] #C往上面的继承顺序
    L[D] = [D,F,H]   #D往上面的继承顺序
    #第二步:A自己的广度,第一层
    L[A] = [B,C,D]
    list = [A,B,C,D,F,E,G,H,O]
    #每个列表的第一个元素为头部,从第一个列表的头部开始找,找其他列表中尾部是否含有
    这个类名,如果没有,提取出来放到一个列表中,如果有,找下一个列表的头部,循环下去
    只要提取来一个,我们就从第一个列表的头部接着重复上面的操作.
    1   [B,D,F,H]  [C,E,G,H]  [D,F,H]  [B,C,D]
    2   [D,F,H]    [C,E,G,H]  [D,F,H]  [C,D]  #提取了头部的B,然后将其他列表头部的B删除,并将B放到list中
    3   [D,F,H]    [E,G,H]  [D,F,H]  [D]      #因为第一个列表的D在其他列表的尾部存在,所以跳过D,然后找第二个列表的头部C,提取了头部的C,然后将其他列表头部的B删除,并将B放到list中
    4   [H]    [H]  [H]  [] 
     
    第二题
    #最高树杈的mro继承顺序
    B 1   [B] [E] [D] [E,D]
      2   [] [E] [D] [E,D]
      3   [] [] [D] [D]
     
    list_B = [B,E,D]
    c 1   [C] [D] [F] [D,F]
      2   [] [D] [F] [D,F]
      3   [] [] [F] [F]
    list_C = [C,D,F]
    A 1 [A] [B,E,D] [C,D,F] [B,C]
      2 [] [B,E,D] [C,D,F] [B,C]
      3 [] [E,D] [C,D,F] [C]
      4 [] [D] [C,D,F] [C]
      5 [] [D] [D,F] []
      6 [] [] [F] []
      6 [] [] [] []
    list_A [A,B,E,C,D,F]
     

      

  • 相关阅读:
    ubuntu16.04解决播放swf视频文件问题
    ubuntu下设置clion是使用clang和clang++
    Linux 下没有conio.h 已解决
    适合最新版docker自定义启动配置
    nginx限制ip并发数
    nginx 403错误
    ubuntu 支持中文
    CentOS 5 上使用yum同时安装32位和64位包的解决方法
    rhel yum报错
    因为swap分区无法启动
  • 原文地址:https://www.cnblogs.com/lynysy/p/9368584.html
Copyright © 2011-2022 走看看