1. 程式人生 > >Python- 接口類-抽象類

Python- 接口類-抽象類

屏幕 設計者 internet test interface %s 處理 img 設備

接口類

繼承有兩種用途:

一:繼承基類的方法,並且做出自己的改變或者擴展(代碼重用)

二:聲明某個子類兼容於某基類,定義一個接口類Interface,接口類中定義了一些接口名(就是函數名)且並未實現接口的功能,子類繼承接口類,並且實現接口中的功能

技術分享圖片
  1 # 一:這樣不好,我要統一一下支付的規則.
  2 
  3 class QQpay:
  4     def pay(self,money):
  5         print(使用qq支付%s元 % money)
  6 
  7 class Alipay:
  8     def pay(self,money):
  9         print
(使用阿裏支付%s元 % money) 10 11 a = Alipay() 12 a.pay(100) 13 14 b = QQpay() 15 b.pay(200) 16 17 # 二,統一支付的規則 歸一化設計,統一 pay接口 18 class QQpay: 19 def pay(self,money): 20 print(使用qq支付%s元 % money) 21 22 class Alipay: 23 def pay(self,money): 24 print(使用阿裏支付%s元 % money)
25 26 def pay(obj,money): 27 obj.pay(money) 28 29 a = Alipay() 30 b = QQpay() 31 32 pay(a,100) 33 pay(b,200) 34 35 # 三,但是,來了一個野生程序員,他不知道你的約定俗成的規則,就會出問題 36 37 class QQpay: 38 def pay(self,money): 39 print(使用qq支付%s元 % money) 40 41 class Alipay: 42 def pay(self,money):
43 print(使用阿裏支付%s元 % money) 44 45 class Wechatpay: 46 def fuqian(self,money): 47 print(使用微信支付%s元 % money) 48 49 def pay(obj,money): 50 obj.pay(money) 51 52 a = Alipay() 53 b = QQpay() 54 55 pay(a,100) 56 pay(b,200) 57 58 c = Wechatpay() 59 c.fuqian(300) 60 61 # 四,解決方式 62 # 定義一個父類,什麽都不寫,只是要求繼承我的所有類有一個pay方法,這樣就制定了一個規範,這就叫做接口類,後者抽象類. 63 class Payment: 64 def pay(self):pass 65 66 class QQpay(Payment): 67 def pay(self,money): 68 print(使用qq支付%s元 % money) 69 70 class Alipay(Payment): 71 def pay(self,money): 72 print(使用阿裏支付%s元 % money) 73 74 class Wechatpay(Payment): 75 def fuqian(self,money): 76 print(使用微信支付%s元 % money) 77 78 79 def pay(obj,money): 80 obj.pay(money) 81 82 a = Alipay() 83 b = QQpay() 84 85 pay(a,100) 86 pay(b,200) 87 88 c = Wechatpay() 89 c.fuqian(300) 90 91 #五,他還是不知道看你這些都繼承了一個類,所以你要制定一個規範,強制他執行. 92 # 創建一個規範 93 from abc import ABCMeta,abstractmethod 94 class Payment(metaclass=ABCMeta): # 抽象類 接口類 規範和約束 metaclass指定的是一個元類 95 @abstractmethod 96 def pay(self):pass # 抽象方法 97 98 class Alipay(Payment): 99 def pay(self,money): 100 print(使用支付寶支付了%s元%money) 101 102 class QQpay(Payment): 103 def pay(self,money): 104 print(使用qq支付了%s元%money) 105 106 class Wechatpay(Payment): 107 # def pay(self,money): 108 # print(‘使用微信支付了%s元‘%money) 109 def recharge(self):pass 110 111 def pay(a,money): 112 a.pay(money) 113 114 a = Alipay() 115 a.pay(100) 116 pay(a,100) # 歸一化設計:不管是哪一個類的對象,都調用同一個函數去完成相似的功能 117 q = QQpay() 118 q.pay(100) 119 pay(q,100) 120 w = Wechatpay() 121 pay(w,100) # 到用的時候才會報錯 122 123 124 125 # 抽象類和接口類做的事情 :建立規範 126 # 制定一個類的metaclass是ABCMeta, 127 # 那麽這個類就變成了一個抽象類(接口類) 128 # 這個類的主要功能就是建立一個規範 129 130 接口類示例
View Code

實踐中,繼承的第一種含義意義並不很大,甚至常常是有害的。因為它使得子類與基類出現強耦合。

繼承的第二種含義非常重要。它又叫“接口繼承”。
接口繼承實質上是要求“做出一個良好的抽象,這個抽象規定了一個兼容接口,使得外部調用者無需關心具體細節,可一視同仁的處理實現了特定接口的所有對象”——這在程序設計上,叫做歸一化。

歸一化使得高層的外部使用者可以不加區分的處理所有接口兼容的對象集合——就好象linux的泛文件概念一樣,所有東西都可以當文件處理,不必關心它是內存、磁盤、網絡還是屏幕(當然,對底層設計者,當然也可以區分出“字符設備”和“塊設備”,然後做出針對性的設計:細致到什麽程度,視需求而定)。

依賴倒置原則:
高層模塊不應該依賴低層模塊,二者都應該依賴其抽象;抽象不應該應該依賴細節;細節應該依賴抽象。換言之,要針對接口編程,而不是針對實現編程

  

在python中根本就沒有一個叫做interface的關鍵字,上面的代碼只是看起來像接口,其實並沒有起到接口的作用,子類完全可以不用去實現接口 ,如果非要去模仿接口的概念,可以借助第三方模塊:

http://pypi.python.org/pypi/zope.interface

twisted的twisted\internet\interface.py裏使用zope.interface

文檔https://zopeinterface.readthedocs.io/en/latest/

設計模式:https://github.com/faif/python-patterns

技術分享圖片
 1 接口提取了一群類共同的函數,可以把接口當做一個函數的集合。
 2 
 3 然後讓子類去實現接口中的函數。
 4 
 5 這麽做的意義在於歸一化,什麽叫歸一化,就是只要是基於同一個接口實現的類,那麽所有的這些類產生的對象在使用時,從用法上來說都一樣。
 6 
 7 歸一化,讓使用者無需關心對象的類是什麽,只需要的知道這些對象都具備某些功能就可以了,這極大地降低了使用者的使用難度。
 8 
 9 比如:我們定義一個動物接口,接口裏定義了有跑、吃、呼吸等接口函數,這樣老鼠的類去實現了該接口,松鼠的類也去實現了該接口,由二者分別產生一只老鼠和一只松鼠送到你面前,即便是你分別不到底哪只是什麽鼠你肯定知道他倆都會跑,都會吃,都能呼吸。
10 
11 再比如:我們有一個汽車接口,裏面定義了汽車所有的功能,然後由本田汽車的類,奧迪汽車的類,大眾汽車的類,他們都實現了汽車接口,這樣就好辦了,大家只需要學會了怎麽開汽車,那麽無論是本田,還是奧迪,還是大眾我們都會開了,開的時候根本無需關心我開的是哪一類車,操作手法(函數調用)都一樣
為什麽使用接口

Python- 接口類-抽象類