接口類和抽象類(都是一種思想概念)python
1、簡單的說明什麼是接口類和抽象類編程
Java主要是面向對象編程的,比較推崇設計模式,而接口是在設計模式裏面的一種思惟概念,因此接口類是Java裏面原生支持的,而python中原生不支持接口類,可是因爲設計模式裏面有接口類這個概念,而python也會用到設計模式的思惟,因此也會接觸到接口類。設計模式
接口類:python原生不支持微信
抽象類:python原生支持app
2、在代碼裏面實現接口類函數
定義幾種支付方式,而且最後統一支付入口,代碼以下:學習
class Wechatpay: def pay(self,money): print('已經使用微信支付了%s元' % money) class Alipay: def pay(self,money): print('已經使用支付寶支付了%s元' % money) # 再定義一個Applepay類 class Aapplepay: def fuqian(self,money): # 這裏不是使用pay函數 print('已經使用蘋果支付了%s元' % money) def pay(pay_obj,money): # 統一支付入口,無論使用哪一種方式,主要就是支付就能夠了 pay_obj.pay(money) wechat = Wechatpay() # 實例化 ali = Alipay() # 實例化 app = Aapplepay() # 實例化 pay(wechat,100) # 經過微信支付100 pay(ali,200) # 經過支付寶支付200 pay(app,300) # 這裏調用pay函數,可是前面Applepay裏面使用的不是pay函數而是fuqian,因此這裏結果將會報錯
運行結果:微信支付
C:\Users\sku1-1\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/sku1-1/PycharmProjects/untitled/學習筆記/接口類和抽象類.py 已經使用微信支付了100元 已經使用支付寶支付了200元 Traceback (most recent call last): File "<encoding error>", line 26, in <module> File "<encoding error>", line 16, in pay AttributeError: 'Aapplepay' object has no attribute 'pay'
從上面的運行結果能夠知道,定義的第三種支付方式,經過統一支付入口後將沒法支付,結果就會報錯,改變一下報錯的方式,以下代碼:spa
# 再定義一個類 class Payment: def pay(self,money): raise NotImplementedError # 報沒有實現這個方法的錯誤,因此能夠知道前面錯誤的地方就應該存在與pay同名的方法 class Wechatpay(Payment): # 繼承Payment類,可是先找本身裏面是否有pay函數,有就用本身的,沒有才找父類 def pay(self,money): print('已經使用微信支付了%s元' % money) class Alipay(Payment): def pay(self,money): # 繼承Payment類,可是先找本身裏面是否有pay函數,有就用本身的,沒有才找父類 print('已經使用支付寶支付了%s元' % money) # 再定義一個Applepay類 class Aapplepay(Payment): # 繼承Payment類,可是先找本身裏面是否有pay函數,有就用本身的,沒有才找父類,由於這裏面沒有pay函數, # 因此執行父類,因此最後將會報’NotImplementedError‘的錯誤 def fuqian(self,money): # 這裏不是使用pay函數 print('已經使用蘋果支付了%s元' % money) def pay(pay_obj,money): # 統一支付入口,無論使用哪一種方式,主要就是支付就能夠了 pay_obj.pay(money) wechat = Wechatpay() # 實例化 ali = Alipay() # 實例化 app = Aapplepay() # 實例化 pay(wechat,100) # 經過微信支付100 pay(ali,200) # 經過支付寶支付200 pay(app,300) # 這裏調用pay函數,可是前面Applepay裏面使用的不是pay函數而是fuqian,因此這裏結果將會報錯
運行結果:設計
已經使用微信支付了100元 Traceback (most recent call last): 已經使用支付寶支付了200元 File "<encoding error>", line 33, in <module> File "<encoding error>", line 23, in pay File "<encoding error>", line 4, in pay NotImplementedError
從代碼中能夠看到,只要你支付方式裏面不存在pay的函數方法,就會直接執行父類payment裏面的pay方法,從然後面直接報本身寫的錯誤,這樣能夠提示出錯的支付方式裏面應該存在
與父類中的pay方法同樣的方法或者函數,可是這樣的報錯方法必需要經過調用pay方法後才能找出錯誤,若是要在不對pay方法進行調用的狀況下就能夠找到錯誤的地方,這樣的代碼改進以下:
from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): # 默認的元類type @abstractmethod def pay(self,money): pass # 只要使用了以上這樣的方法就代表已經創建一個規範,規範下面全部的代碼,使得如下的代碼都應該存在與pay同名的方法, # 不存在就沒法進行,就會報錯,並且報錯方法還會具體指出錯誤所在 class Wechatpay(Payment): # 繼承Payment類,可是先找本身裏面是否有pay函數,有就用本身的,沒有才找父類 def pay(self,money): print('已經使用微信支付了%s元' % money) class Alipay(Payment): def pay(self,money): # 繼承Payment類,可是先找本身裏面是否有pay函數,有就用本身的,沒有才找父類 print('已經使用支付寶支付了%s元' % money) # 再定義一個Applepay類 class Aapplepay(Payment): # 繼承Payment類,可是先找本身裏面是否有pay函數,有就用本身的,沒有才找父類,由於這裏面沒有pay函數, # 因此執行父類,因此最後將會報’NotImplementedError‘的錯誤 def fuqian(self,money): # 這裏不是使用pay函數 print('已經使用蘋果支付了%s元' % money) def pay(pay_obj,money): # 統一支付入口,無論使用哪一種方式,主要就是支付就能夠了 pay_obj.pay(money) wechat = Wechatpay() # 實例化 ali = Alipay() # 實例化 app = Aapplepay() # 實例化 # 使用了開頭的規範後,就不須要在進行調用方法pay才能夠報錯了了,直接進行實例化就能夠, # 這樣方便寫代碼的人很快就能夠找出錯誤所在 # pay(wechat,100) # 經過微信支付100 # pay(ali,200) # 經過支付寶支付200 # pay(app,300) # 這裏調用pay函數,可是前面Applepay裏面使用的不是pay函數而是fuqian,因此這裏結果將會報錯
運行結果:
Traceback (most recent call last): File "<encoding error>", line 32, in <module> TypeError: Can't instantiate abstract class Aapplepay with abstract methods pay
這樣就能夠引出用代碼實現接口類的大體結構,相似的結構以下所示:
from abc import abstractmethod,ABCMeta class Payment(metaclass=ABCMeta): # 默認的元類type @abstractmethod def pay(self,money): # 規範子類必須含有pay方法 pass class A(Payment): def pay(self,money):pass class B(Payment): def pay(self,money):pass class C(Payment): def pay(self,money):pass
其實接口類和抽象類都是起到一個規範子類,約束子類的一個做用,不一樣的地方是:
接口類:支持多繼承,接口類中的全部方法都必須不能實現,這樣才能起到規範的做用---Java中
抽象類:不支持多繼承,抽象類中的方法能夠有一些代碼的實現---Java中