接口类
接口类:python原生不支持的
抽象类:python原生支持的
导引:写一个支付的程序
class Wechat: def pay(self,money): print('使用微信支付了%s元'%money) class Alipay: def pay(self,money): print('使用支付宝支付了%s元' % money) wechat=Wechat() wechat.pay(100) Ali=Alipay() Ali.pay(100)
这段代码初步实现了支付的功能,但是在实际使用的时候不关心消费者使用的是什么支付方式,只要收钱就可以
class Wechat: def pay(self,money): print('使用微信支付了%s元'%money) class Alipay: def pay(self,money): print('使用支付宝支付了%s元' % money) def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj pay_obj.pay(money) wechat=Wechat() Ali=Alipay() pay(wechat,100) pay(Ali,100)
进阶
class Wechat: def pay(self,money): print('使用微信支付了%s元'%money) class Alipay: def pay(self,money): print('使用支付宝支付了%s元' % money) class Appplepay: def fuqian(self,money):#假如新来的员工不会写英文,那么这里就出现了中文的fuqian print('使用Appplepay支付了%s元' % money) def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj pay_obj.pay(money) wechat=Wechat() Ali=Alipay() App=Appplepay() pay(wechat,100) pay(Ali,100) pay(App,100)#因为在apppay中并没有pay这个函数,所以这里一定会报错
那么如何出现这个报错呢
class Payment: def pay(self,money): raise NotImplemented#这里表示没有实现这个功能 class Wechat(Payment): def pay(self,money): print('使用微信支付了%s元'%money) class Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元' % money) class Appplepay(Payment): def fuqian(self,money):#假如新来的员工不会写英文,那么这里就出现了中文的fuqian print('使用Appplepay支付了%s元' % money) def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj pay_obj.pay(money) wechat=Wechat() Ali=Alipay() App=Appplepay() pay(wechat,100) pay(Ali,100) pay(App,100)#因为在apppay中并没有pay这个函数,所以这里一定会报错 D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py 使用微信支付了100元 Traceback (most recent call last): 使用支付宝支付了100元 File "F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py", line 25, in <module> pay(App,100)#因为在apppay中并没有pay这个函数,所以这里一定会报错 File "F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py", line 18, in pay pay_obj.pay(money) File "F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py", line 3, in pay raise NotImplemented#这里表示没有实现这个功能 TypeError: exceptions must derive from BaseException Process finished with exit code 1
这里,将支付的方法定义为一个父类,然后继承,当下面支付的函数,如果没有按照父类中的形式来写的时候,就会报错,这样一看到出现这个错误,就知道在下面的支付方式的地方写错了
当修改了苹果pay后的代码
class Payment: def pay(self,money): raise NotImplemented#这里表示没有实现这个功能 class Wechat(Payment): def pay(self,money): print('使用微信支付了%s元'%money) class Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元' % money) class Appplepay(Payment): def pay(self,money):#修改为pay print('使用Appplepay支付了%s元' % money) def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj pay_obj.pay(money) wechat=Wechat() Ali=Alipay() App=Appplepay() pay(wechat,100) pay(Ali,100) pay(App,100) D:\anoconda\python.exe F:/python/python学习/人工智能/第一阶段day2/3.二分查找算法.py 使用微信支付了100元 使用支付宝支付了100元 使用Appplepay支付了100元 Process finished with exit code 0
上面的代码运行正常
正式引入接口类的定义
from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod def pay(self,money):pass #这里的规范对于下面只是一个约束的作用,规范了支付的正式写法。这里就是一个接口类 #接口类:默认多继承,所有的方法都必须不能实现,就是方法后面是pass——java #抽象类:不支持多继承,抽象类中可以有些代码的实现——java class Wechat(Payment): def pay(self,money): print('使用微信支付了%s元'%money) class Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元' % money) class Appplepay(Payment): def fuqian(self,money):#修改为pay print('使用Appplepay支付了%s元' % money) def pay(pay_obj,money):#这里线定义了一个支付的对象,pay_obj pay_obj.pay(money) wechat=Wechat() Ali=Alipay() App=Appplepay() pay(wechat,100) pay(Ali,100) pay(App,100)
接口类的多继承
导引,进入动物园,希望利用函数能够描述所有动物的行为,但是下面的显然不能满足要求
class Animal: def walk(self): pass def flying(self): pass def swim(self): pass Tiger=Animal()#但是老虎不会游泳
可以这样
class Swan: def walk(self): pass def flying(self): pass class Hawk: def walk(self): pass def flying(self): pass class Tiger: def walk(self): pass def flying(self): pass
实现了功能,但是代码数量太多
此时可以使用接口类的多继承
首先是继承
class Swim_Animal: def swim(self): pass class Walk_Animal: def swim(self): pass class Fly_Animal: def swim(self): pass class Tiger(Walk_Animal,Swim_Animal):pass class Hawk(Fly_Animal,Fly_Animal):pass class Swan(Walk_Animal,Fly_Animal):pass
其次,这里面有很多的同类型的代码,那么防止写错就需要用到接口
from abc import abstractmethod,ABCMeta class Swim_Animal: @abstractmethod def swim(self): pass class Walk_Animal: @abstractmethod def walk(self): pass class Fly_Animal: @abstractmethod def fly(self): pass class Tiger(Walk_Animal,Swim_Animal): def walk(self): pass def swim(self): pass class Hawk(Fly_Animal,Walk_Animal):pass class Swan(Walk_Animal,Fly_Animal):pass
抽象类
什么是抽象类
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
为什么要有抽象类
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案
#在操作系统中一切皆文件 import abc #利用abc模块实现抽象类 class All_file(metaclass=abc.ABCMeta): all_type='file' @abc.abstractmethod #定义抽象方法,无需实现功能 def read(self): '子类必须定义读功能' pass @abc.abstractmethod #定义抽象方法,无需实现功能 def write(self): '子类必须定义写功能' pass # class Txt(All_file): # pass # # t1=Txt() #报错,子类没有定义抽象方法 class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法 def read(self): print('文本数据的读取方法') def write(self): print('文本数据的读取方法') class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法 def read(self): print('硬盘数据的读取方法') def write(self): print('硬盘数据的读取方法') class Process(All_file): #子类继承抽象类,但是必须定义read和write方法 def read(self): print('进程数据的读取方法') def write(self): print('进程数据的读取方法') wenbenwenjian=Txt() yingpanwenjian=Sata() jinchengwenjian=Process() #这样大家都是被归一化了,也就是一切皆文件的思想 wenbenwenjian.read() yingpanwenjian.write() jinchengwenjian.read() print(wenbenwenjian.all_type) print(yingpanwenjian.all_type) print(jinchengwenjian.all_type)
一般情况下,单继承能够实现的功能都是一样的,所以在父类中可以有一些简单的基础实现
多继承的情况,由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中。
比如
#在操作系统中一切皆文件 import abc #利用abc模块实现抽象类 class All_file(metaclass=abc.ABCMeta): all_type='file' @abc.abstractmethod #定义抽象方法,无需实现功能 def read(self): '子类必须定义读功能' with open('filename') as f: pass#这样能够将下面对文件的操作提到上面来 @abc.abstractmethod #定义抽象方法,无需实现功能 def write(self): '子类必须定义写功能' pass
python中没有接口类,java里不支持多继承,所以它创造了接口interface这个概念,那么interface这个数据类型就能够在java中实现多继承。不能实例化
python中自带多继承,所以我们直接哦那个class来实现了接口类
python中支持抽象类,一般情况下单继承,因为java里面抽象类只支持单继承;
java里面所有的继承都是单继承,所以抽象类完美的解决了单继承需求中的规范问题。
但对于多继承的需求,由于java本身的语法不支持,所以创建了接口interface这个概念来解决多继承的问题
python中没有接口类,但是有抽象类,通过abc模块中的metacclass=ABC,@abstrud
本质是做代码规范用的,希望在子类中实现和父类方法名字完全一样的方法
接口类和抽象类的区别:
在java的角度看是有区别的:
java没有多继承,所以为了接口隔离原则,设计了接口这个概念,支持多继承
java本来就支持单继承,所以就有了抽象类。
python既支持单继承也支持多继承,所以对于接口类和抽象类的区别就不那么明显了
甚至在python中并没有内置接口类