类与类之间的关系:
依赖关系
关联关系
聚合关系
组合关系
依赖关系: 大象与冰箱的例子
# 依赖关系,冰箱依赖大象打开 class Elephant: def __init__(self,name): self.name = name def open_bx(self,obj): # obj = b1 obj.open() print('冰箱被打开') def close_bx(self,obj): obj.close() print('冰箱被关闭') class Binx: def __init__(self,name): self.name = name def open(self): print('1,2,3,开') def close(self): print('1,2,3,关') e1 = Elephant('陈臭屁') b1 = Binx('Media') e1.open_bx(b1) # 传b1让obj接收
依赖关系:给一个类的方法传了一个参数此参数是另一个类的对象(类名)。
(给大象打开冰箱的方法,传一个冰箱的对象)
这种依赖关系是所有关系中紧密型最低的,耦合性最低的。
关联关系
class Boy: def __init__(self, name, girlfriend=None): self.name = name self.girlfriend = girlfriend def have_a_dinner(self): if self.girlfriend: print('%s 和 %s 一起共度晚餐'%(self.name,self.girlfriend.name)) else: print('单身狗吃什么吃') def append_girl(self,girl): # 添加女朋友 self.girlfriend = girl # 关联 Girl类 def remove_girl(self): # 与女朋友分手 self.girlfriend = None class Girl: def __init__(self, name): self.name = name # 起初创业没有女朋友 b = Boy('alex') # b.have_a_dinner() # 突然有一天 alex 家 拆迁,有女朋友了 g = Girl('如花') # print(g.name) b.append_girl(g) b.have_a_dinner() # # # wusir 娃娃亲 # gg = Girl('金莲') # # wu = Boy('武大',gg) # wu.have_a_dinner() # # 西门太白出现。 # gg = Girl('金莲') # # wu = Boy('武大',gg) # # 女朋友失去了 # wu.remove_girl() # wu.have_a_dinner()
class School: def __init__(self,name,address): self.name = name self.address = address self.teacher_list = [] def append_teacher(self,teacher): self.teacher_list.append(teacher) class Teacher: def __init__(self, name,comment,school): self.name = name self.comment = comment self.school = school def check_address(self): print('%s 在%s 办公'%(self.name,self.school.address)) beijing = School('老男孩北京校区','美丽富饶的沙河') shanghai = School('老男孩上海校区','上海漳江新区') shenzhen = School('老男孩深圳校区','南山区平山村儿') t1 = Teacher('太白','优秀',beijing) t2 = Teacher('景女神','优秀',beijing) t3 = Teacher('文周','优秀',beijing) # t2 = Teacher('海峰','优秀',shanghai) # t3 = Teacher('日天','看吧',shenzhen) # t1.check_address() beijing.append_teacher(t1) beijing.append_teacher(t2) beijing.append_teacher(t3) # print(beijing.teacher_list) for i in beijing.teacher_list: print(i.name)
多继承
Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和C3算法。
- 当类是经典类时,多继承情况下,会按照深度优先方式查找。
- 当类是新式类时,多继承情况下,会按照C3算法去查询。
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
class X: pass class S(X): pass class A(X): pass class B(S): pass class C(A): pass class D(B): pass class E(C): pass class F(D,E,B): pass f1 = F() print(F.mro()) #[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
C3算法
# 新式类: class A: pass class B: pass class C(B,A): pass # mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] ) # mro(C) = mro(C(B,A)) = [C] + merge(mro(B),mro(A),[B,A]) class D: pass class E(D): pass # # [E,D]
# 表头 表尾 # 表头 列表的第一个元素 # 表尾 列表中表头以外的元素集合(可以为空) # [A,B,D,C] A表头 BDC 表尾 # merge( [E,O], [C,E,F,O], [C] ) # 取出第一个列表的表头 E 所有列表的表尾 O E F O '' # 如果E 在所有的表尾中,那么就跳过这个列表 # merge( [E,O], [C,E,F,O], [C] ) # 第二个列表表头: C O EFO '' 将C 单独提出 # [c] + merge([E,O], [E,F,O])
上图用C3算法,求mro顺序
mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C]) mro(B) = mro(B(D,E)) mro(B(D,E)) = [B] + merge(mro(D),mro(E),[D,E]) mro(B(D,E)) = [B] + merge([D,O],[E,O],[D,E]) # D E都是单继承,所以mro(D)=[D,O] , mro(E)=[E,O] mro(B(D,E)) = [B,D] + merge([O],[E,O],[E]) mro(B(D,E)) = [B,D,E] + merge([O],[O]) mro(B(D,E)) = [B,D,E,O] mro(C) = mro(C(E,F)) mro(C(E,F)) = [C] + merge([E,O],[F,O],[E,F]) mro(C(E,F)) = [C,E] + merge([O],[F,O],[F]) mro(C(E,F)) = [C,E,F] + merge([O],[O]) mro(C(E,F)) = [C,E,F,O] # 计算总的: mro(A(B,C)) = [A] + merge([B,D,E,O],[C,E,F,O],[B,C]) mro(A(B,C)) = [A,B] + merge([D,E,O],[C,E,F,O],[C]) mro(A(B,C)) = [A,B,D] + merge([E,O],[C,E,F,O],[C]) mro(A(B,C)) = [A,B,D,C] + merge([E,O],[E,F,O]) mro(A(B,C)) = [A,B,D,C,E] + merge([O],[F,O]) mro(A(B,C)) = [A,B,D,C,E,F] + merge([O],[O]) mro(A(B,C)) = [A,B,D,C,E,F,O]
# super遵循mro
class O: def func(self): print('in O') class D(O): pass # def func(self): # print('in D') class E(O): pass # def func(self): # print('in E') class F(O): def func(self): print('in F') class B(D,E): pass # def func(self): # print('in B') class C(E,F): pass # def func(self): # print('in C') class A(B,C): def func(self): super().func() print('in A') obj = A() obj.func() mro(A(B,C)) = [A,B,D,C,E,F,O] print(A.__mro__) # super 遵循mro 顺序