python基础 day25 面向对象—继承顺序、抽象类、

一、今日内容

回顾

# 继承 是通过继承来解决代码重用的问题

继承(进阶的知识点)

# 多继承的继承顺序问题(项目和源码)
# 通过继承实现的类的开发规范(工作中)

多态

# 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):
   @abstractmethod
   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))

WeChat('alex')

 

抽象类我已经写好了 要求你根据已经写好的Payment实现WeChatAlipay

原文地址:https://www.cnblogs.com/iaoyuyuyuhuanghuang/p/14268641.html