继承(进阶的知识点)
通过集成来解决代码复用问题
? 多继承态顺序问题(项目和源码)
? 通过继承实现的类的开发规范(工作中)
多态
python 当中处处是多态, 一切是对象
什么是多态 借助 java
鸭子类型
背诵
python3 所有的类都继承 object 类
只要继承 object 的类就是新式类
python3 中所有的类都是新式类
py3 中 : 所有的类都继承 object 类 都是新式类
py2 中 : 不继承 object 的类都是经典类
? 继承 object 的类 就是新式类
经典类: 在 py3 中不存在, py2 中 不继承 object 的类都是经典类
#py2 中
class A: pass 经典类
class B(object): pass 新式类
#py3 中
class A: pass 新式类
class B(object): pass 新式类
在单继承方面(无论是新式类还是经典类)
- class A:
- def func(self):pass
- class B(A):
- def func(self):pass
- class C(B):
- def func(self):pass
- class D(C):
- def func(self):pass
- d=D()
多继承
寻找某一个方法的顺序 d->D->C->B->A 深度优先
越往父类走, 是深度
- class A:
- def func(self):
- print('A')
- class B(A):
- def func(self):
- print('B')
- class C(A):
- def func(self):
- print('C')
- class D(B,C):
- def func(self):
- print('D')
- d=D()
- d.func()
- #
- # A
- # -> <-
- # B C
- # <--->
- # D
- #
- # 新式类 D-B-C-A 现在 广度优先
- # 走到一个点, 下一个点即可以从深度走, 也可以从广度走 总是先走广度再走深度 广度优先
- # 广度优先奇奇怪怪
- # 经典类 D-B--A--C 早期的一个类 深度优先
- # 经典类中 都是深度优先 总是在一条路走不通, 退回另外一条最近的路
- # C3 算法
- #
- # A(O)=[AO]
- # B(A)=[BAO]
- # C(A)=[CAO]
- # D(B)=[DBAO]
- # E(C)=[ECAO]
- # F(D,E)=C3(D(B)+E(C))
- # F=[F]+[DBAO]+[ECAO]
- # [F]+ (F 提出来)
- # F=[DBAO]+[ECAO]
- # FD=[BAO]+[ECAO]
- # FDB=[AO]+[ECAO]
- # FDBE=[AO]+[CAO]
- # FDBEC=[AO]+[AO]
- # FDBECA=[O]+[O]
- # FDBECAO
- # 算法的内容
- # 如果是单继承 那么总是子类 ->父类 顺序查找计算
- # 如果是多继承
- #
- # a
- # | |
- # b c
- # | |
- # d e
- # |
- # f
- # 广度优先 fdbeca 到最上面一时, 然后换用第二条路开始走 直接走到最上面
- # merge 原则
- # 到最上面一时, 然后换用第二条路开始走 直接走到最上面
- # 深度优先 广度优先不一样
- # 经典类 -- 深度优先 新式类 -- 广度优先
- # 深度优先 要会看, 能自己搞出顺序来
- # 深度优先要会用 mro 会查看顺序
- # 经典类没有 mro 但新式类有
- class A:
- def func(self):
- print('A')
- class B(A):
- def func(self):
- print('B')
- class C(A):
- def func(self):
- print('C')
- class D(B,C):
- def func(self):
- print('D')
- d=D()
- d.func()
- print(D.mro())
- # 结果
- #[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
- class Payment:
- def pay(self):
- raise NotImplementedError('请在子类中重写同名 pay 方法')
- #主动抛异常
- class Alipay:
- def __init__(self,name):
- self.name=name
- def pay(self,money):
- dic={'uname':self.name,'money':money}
- print(f'{self.name}通过支付宝支付 {money} 元成功')
- class Wechat:
- def __init__(self,name):
- self.name=name
- def pay(self,money):
- dic={'username':self.name,'money':money}
- print(f'{self.name}通过微信支付 {money} 元成功')
- aw=Wechat('alex')
- aw.pay(400)
- aw=Alipay('alex')
- aw.pay(400)
- # alex 通过微信支付 400 元成功
- # alex 通过支付宝支付 400 元成功
- # / 改进
- # 归化式设计 聚合支付
- def pay(name,price,kind):
- if kind ==Wechat:
- obj= Wechat(name)
- if kind ==Alipay:
- obj= Wechat(name)
- obj.pay(price)
- pay('name',1231231,Alipay)
- # name 支付 1231231 元成功
- ? raise NotImplementedError
- ? raise NotImplementedError('你没有按要求使用')
- # 多态 一个类型变现出来的多种状态
- # 支付 便显出微信支付和苹果支付 这两种状态
- # 在 java 中 一个参数必须指定类型
- # 所以两个类型的对象都可以传, 那么必须让两个类继承自一个父类
- # 在指定类型的时候让我们的父类来指定
- class Wechat():
- def __init__(self,name):
- self.name=name
- def pay(self,money):
- dic={'username':self.name,'money':money}
- print(f'{self.name}通过微信支付 {money} 元成功')
- class Apple():
- def __init__(self,name):
- self.name=name
- def pay(self,money):
- dic={'name':self.name,'number':money}
- # 想办法调用苹果支付多少多少钱
- print(f'{self.name}通过 Apple pay 支付 {money} 元成功')
- def pay(a,b):
- a.pay(b)
- a=Apple('alex')
- pay(a,400)
- a=Wechat('alex')
- pay(a,400)
- #
- # #java 类型的
- # def pay(Payment obj,int money):
- # obj.pay(400)
- # obj=Apple('alex')
- # pay(obj,400)
- #
- # obj=Wechat('alex')
- # pay(obj,400)
- #
- # class list:
- # def __init__(self,*args):
- # self.l=[1,2,3]
- #
- # def __len__(self):
- # n=0
- # for i in self.l:
- # n+=1
- # return n
- # l=[1,2,3]
- # l.append(4)
- # def len(obj):
- # return obj.__len__()
- print(dir(list))
- # 所有实现__len__ 方法的类, 在调用函数的时候 obj 都说是鸭子类型
- # 迭代器协议 __iter__ __next__ 是迭代器
- # 例子
- class range:
- def __init__(self):
- pass
- def __next__(self):
- pass
- # 看起来像, 而不需要继承来实现 不必说继承自 迭代器 class range(迭代器):pass
- # add 内部实现了 __add__ 他就是鸭子类型的
- # 1+2
- # [1]+[2]
- # 这是 java 多态方法
- class lenpyte:pass
- class list(lenpyte):pass
- class set(lenpyte):pass
- class dict(lenpyte):pass
- class list(lenpyte):pass
- class tuple(lenpyte):pass
- class str(lenpyte):pass
- def len(obj):
- pass
- len(list)
- len(set)
- len(dict)
- len(str)
- len(tuple)
- # python 不用继承父类 只用让它看起来像
- class list:
- def __len__(self):
- pass
- class dict:
- def __len__(self):
- pass
- class tuple:
- def __len__(self):
- pass
- class str:
- def __len__(self):
- pass
- # def len(鸭子类型 看起来有没有实现一个__len__ obj):
- # pass
来源: http://www.bubuko.com/infodetail-3458951.html