继承

继承

1.初识继承

继承:子类可以使用父类的各种属性和方法
    如果B类继承A类,B类就称为子类,派生类,A类就称为父类,基类,超类.
继承分为 单继承 和 多继承
继承的优点:
    1.减少重复代码
    2.增加类之间的耦合性(耦合性不宜多,宜精)
    3.使代码更加清晰,流畅

例:
class Animal:           #父类,基类,超类
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
        
class Person(Animal):     #子类,派生类
    pass
class Cat(Animal):        #子类,派生类
    pass
class Dog(Animal):        #子类,派生类
    pass

2.单继承

1.类名执行父类属性方法

class Animal: 
    type_name = "动物类"
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def eat(self):
        print("吃东西")
class Person(Animal):     #子类,派生类
    def eat(self):
        print("吃饭")
class Cat(Animal):        #子类,派生类
    pass
class Dog(Animal):        #子类,派生类
    pass

print(Person.type_name)    #动物类
Person.eat(11)             #吃东西

2.派生类对象,执行父类的属性方法
  查询顺序单项不可逆:子类使用父类的属性方法,父类不能使用子类的属性方法

p = Person("奇奇","男",18)
p.eat()                    #吃饭

3.既要执行子类的方法,又要执行父类的方法
  方法1 : 不依赖于继承关系
  方法2 : super()

class Animal: 
    type_name = "动物类"
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
    def eat(self):
        print("吃东西")
class Person(Animal):     #子类,派生类
    def __init__(self,name,sex,age,mind):
       #Animal.__init__(self,name,sex,age)  --方法1
       #super().__init__(name,sex,age)    --方法2
        self.mind = mind
    def eat(self):
        print("吃饭")
        
qiqi = Person("奇奇","男",18,"有脑子")

3.多继承

python类分为两种
python2x: python2.2之前都是经典类,python2.2以后,经典类与新式类并存
python3x: 全部都是新式类

经典类:不继承object类,查询时遵循深度优先原则
新式类:继承object类,查询时遵循mro(C3)算法


class ShenXian:
    def fly(self):
        print("神仙都会飞")
    def walk(self):
        print("神仙都走路")
class Monkey:
    def fly(self):
        print("猴子也能飞")
    def walk(self):
        print("猴子也走路")
class SunWuKong(ShenXian,Monkey):   #多继承
    pass
s = SunWuKong()
s.fly()
s.walk()

在多继承中,当两个父类中出现重名方法中时,涉及到一个顺序问题
深度优先:从头开始,从左往右,一条路走到头,然后回头,继续一条路走到头
    
新式类的多继承:
MRO序列
通用公式:
mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
(其中Child继承自Base1, Base2)

表头和表尾:
表头:列表的第一个元素
表尾:列表中表头以外的元素集合(可以为空)
+操作:[A] + [B] = [A,B]

    
merge 操作示例:
    如计算merge( [E,O], [C,E,F,O], [C] )
有三个列表 :  ①      ②          ③
1 merge不为空,取出第一个列表列表①的表头E,进行判断                    各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
2 取出列表②的表头C,进行判断
   C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
   merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
3 进行下一次新的merge操作 ......
--------------------- 

计算mro(A)操作
class O:
    pass
class D(O):
    pass
class E(o):
    pass
class F(O):
    pass
class B(D,E):
    pass
class C(E,F):
    pass
class A(B,C):
    pass

原式 = [A] + merge(mro(B),mro(C),[B,C])

mro(B) = mro(B(D,E))
       = [B]+merge(mro(D),mro(E),[D,E])
       = [B]+merge([D,O],[E,O],[D,E])
       = [B,D]+merge([O],[E,O],[E])
       = [B,D,E]+merge([O],[O])
       = [B,D,E,O]
mro(C) = mro(C[E,F])
       = [C]+merge(mro(E),mro[F],[E,F])
       = [C]+merge([E,O],[F,O],[E,F])
       = [C,E]+merge([O],[F,O],[F])
       = [C,E,F]+merge([O],[O])
       = [C,E,F,O]
原式 = [A] + merge([B,D,E,O],[C,E,F,O],[B,C])
	= [A,B] + merge([D,E,O],[C,E,F,O],[C])
    = [A,B,D] + merge([E,O],[C,E,F,O],[C])
    = [A,B,D,C] + merge([E,O],[E,F,O])
    = [A,B,D,C,E] + merge([O],[F,O])
    = [A,B,D,C,E,F] + merge([O],[O])
    = [A,B,D,C,E,F,O]
    
可以直接print(A.mro())查看查找顺序
posted @ 2019-08-06 21:38  Bugbiss  阅读(116)  评论(0编辑  收藏  举报