继承
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())查看查找顺序