回顾
# 继承 是通过继承来解决代码重用的问题
继承(进阶的知识点)
# 多继承的继承顺序问题(项目和源码)
# 通过继承实现的类的开发规范(工作中)
多态
# python当中处处是多态,一切皆对象
# 什么是多态,借助java
# 鸭子类型
# raise ValueError
# raise IndexError
# raise KeyError('提示信息')
# raise NotImplementedError('你没有按照要求实现函数')
背诵
只要继承object类就是新式类
不继承object类的都是经典类
python3 所有的类都继承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->C->B->A
多继承
class A:
def func(self):
print('A')
class B(A):
pass
# def func(self):
# print('B')
class C(A):
pass
# def func(self):
# print('C')
class D(B,C):
pass
# def func(self):
# print('D')
print(D.mro()) # 只在新式类中有,经典类没有的
d = D()
d.func()
在走到一个点,下一个点既可以从深度走,也可以从广度走的时候,总是先走广度,再走深度,广度优先
在经典类中,都是深度优先,总是在一条路走不通之后再换一条路,走过的点不会再走了
C3算法
A(O) = [AO]
B(A) = [BAO]
C(A) = [CAO]
D(B) = [DBAO]
E(C) = [ECAO]
F(D,E) = merge(D(B) + E(C))
= [F] + [DBAO] + [ECAO]
F = [DBAO] + [ECAO]
FD = [BAO] + [ECAO]
FDB = [AO] + [ECAO]
FDBE = [AO] + [CAO]
FDBEC= [AO] + [AO]
FDBECA= [O] + [O]
FDBECAO
算法的内容
# 如果是单继承 那么总是按照从子类->父类的顺序来计算查找顺序
# 如果是多继承 需要按照自己本类,父类1的继承顺序,父类2的继承顺序,...
# merge的规则 :如果一个类出现在从左到右所有顺序的最左侧,并且没有在其他位置出现,那么先提出来作为继承顺序中的一个
# 或 一个类出现在从左到右顺序的最左侧,并没有在其他顺序中出现,那么先提出来作为继承顺序中的一个
# 如果从左到右第一个顺序中的第一个类出现在后面且不是第一个,那么不能提取,顺序向后继续找其他顺序中符合上述条件的类
经典类 - 深度优先 新式类 - 广度优先
深度优先要会看,自己能搞出顺序来
广度优先遵循C3算法,要会用mro,会查看顺序
经典类没有mro,但新式类有
普通的类 抽象类 是一个开发的规范 约束它的所有子类必须实现一些和它同名的方法 支付程序 微信支付 url连接,告诉你参数什么格式 {'username':'用户名','money':200} 支付宝支付 url连接,告诉你参数什么格式 {'uname':'用户名','price':200} 苹果支付
class Payment: # 抽象类
def pay(self,money):
'''只要你见到了项目中有这种类,你要知道你的子类中必须实现和pay同名的方法'''
raise NotImplementedError('请在子类中重写同名pay方法')
class Alipay(Payment):
def __init__(self,name):
self.name = name
def pay(self,money):
dic = {'uname':self.name,'price':money}
# 想办法调用支付宝支付 url连接 把dic传过去
print('%s通过支付宝支付%s钱成功'%(self.name,money))
class WeChat(Payment):
def __init__(self,name):
self.name = name
def pay(self,money):
dic = {'username':self.name,'money':money}
# 想办法调用微信支付 url连接 把dic传过去
print('%s通过微信支付%s钱成功'%(self.name,money))
class Apple(Payment):
def __init__(self,name):
self.name = name
def pay(self,money):
dic = {'name': self.name, 'number': money}
# 想办法调用苹果支付 url连接 把dic传过去
print('%s通过苹果支付%s钱成功' % (self.name, money))
aw = WeChat('alex')
aw.pay(400)
aa = Alipay('alex')
aa.pay(400)
归一化设计
def pay(name,price,kind):
if kind == 'Wechat':
obj = WeChat(name)
elif kind == 'Alipay':
obj = Alipay(name)
elif kind == 'Apple':
obj = Apple(name)
obj.pay(price)
pay('alex',400,'Wechat')
pay('alex',400,'Alipay')
pay('alex',400,'Apple')
appa = Apple('alex')
appa.fuqian(500)
实现抽象类的另一种方式,约束力强,依赖abc模块
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
抽象类我已经写好了