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]
 

 

 

 

 

  

posted on 2018-07-26 18:17  意难平嗯嗯  阅读(106)  评论(0编辑  收藏  举报

导航