標籤:抽象類別 耦合 def 設計 port pack meta targe pass
1、抽象類別 --類似介面
介面的概念:
自己提供給使用者來調用自己功能的方式\方法\入口,
1.1、java中介面 interface
=================第一部分:Java 語言中的介面很好的展現了介面的含義: IAnimal.java/** Java的Interface介面的特徵:* 1)是一組功能的集合,而不是一個功能* 2)介面的功能用於互動,所有的功能都是public,即別的對象可操作* 3)介面只定義函數,但不涉及函數實現* 4)這些功能是相關的,都是動物相關的功能,但光合作用就不適宜放到IAnimal裡面了 */package com.oo.demo;public interface IAnimal { public void eat(); public void run(); public void sleep(); public void speak();}=================第二部分:Pig.java:豬”的類設計,實現了IAnnimal介面 package com.oo.demo;public class Pig implements IAnimal{ //如下每個函數都需要詳細實現 public void eat(){ System.out.println("Pig like to eat grass"); } public void run(){ System.out.println("Pig run: front legs, back legs"); } public void sleep(){ System.out.println("Pig sleep 16 hours every day"); } public void speak(){ System.out.println("Pig can not speak"); }}=================第三部分:Person2.java/**實現了IAnimal的“人”,有幾點說明一下: * 1)同樣都實現了IAnimal的介面,但“人”和“豬”的實現不一樣,為了避免太多代碼導致影響閱讀,這裡的代碼簡化成一行,但輸出的內容不一樣,實際項目中同一介面的同一功能點,不同的類實現完全不一樣* 2)這裡同樣是“人”這個類,但和前面介紹類時給的類“Person”完全不一樣,這是因為同樣的邏輯概念,在不同的應用情境下,具備的屬性和功能是完全不一樣的 */package com.oo.demo;public class Person2 implements IAnimal { public void eat(){ System.out.println("Person like to eat meat"); } public void run(){ System.out.println("Person run: left leg, right leg"); } public void sleep(){ System.out.println("Person sleep 8 hours every dat"); } public void speak(){ System.out.println("Hellow world, I am a person"); } }
1.2、為何要用介面
介面提取了一群類共同的函數,可以把介面當做一個函數的集合。然後讓子類去實現介面中的函數。這麼做的意義在于歸一化,什麼叫歸一化,就是只要是基於同一個介面實現的類,那麼所有的這些類產生的對象在使用時,從用法上來說都一樣。歸一化的好處在於:歸一化讓使用者無需關心對象的類是什麼,只需要的知道這些對象都具備某些功能就可以了,這極大地降低了使用者的使用難度。
歸一化使得高層的外部使用者可以不加區分的處理所有介面相容的對象集合
就好象linux的泛檔案概念一樣,所有東西都可以當檔案處理,不必關心它是記憶體、磁碟、網路還是螢幕(當然,對底層設計者,當然也可以區分出“字元裝置”和“塊裝置”,然後做出針對性的設計:細緻到什麼程度,視需求而定)。
再比如:我們有一個汽車介面,裡面定義了汽車所有的功能,然後由本田汽車的類,奧迪汽車的類,福士汽車的類,
他們都實現了汽車介面,這樣就好辦了,大家只需要學會了怎麼開汽車,那麼無論是本田,還是奧迪,還是福士我們都會開了,開的時候根本無需關心我開的是哪一類車,操作手法(函數調用)都一樣
2、模仿interface
在python中根本就沒有一個叫做interface的關鍵字,如果非要去模仿介面的概念
可以藉助第三方模組:http://pypi.python.org/pypi/zope.interface
也可以使用繼承,其實繼承有兩種用途
一:繼承基類的方法,並且做出自己的改變或者擴充(代碼重用):實踐中,繼承的這種用途意義並不很大,甚至常常是有害的。因為它使得子類與基類出現強耦合。
二:聲明某個子類相容於某基類,定義一個介面類(模仿java的Interface),介面類中定義了一些介面名(就是函數名)且並未實現介面的功能,子類繼承介面類,並且實現介面中的功能
class Interface:#定義介面Interface類來模仿介面的概念,python中壓根就沒有interface關鍵字來定義一個介面。 def read(self): #定介面函數read pass def write(self): #定義介面函數write passclass Txt(Interface): #文本,具體實現read和write def read(self): print(‘文本資料的讀取方法‘) def write(self): print(‘文本資料的讀取方法‘)class Sata(Interface): #磁碟,具體實現read和write def read(self): print(‘硬碟資料的讀取方法‘) def write(self): print(‘硬碟資料的讀取方法‘)class Process(Interface): def read(self): print(‘進程資料的讀取方法‘) def write(self): print(‘進程資料的讀取方法‘)
上面的代碼只是看起來像介面,其實並沒有起到介面的作用,子類完全可以不用去實現介面 ,這就用到了抽象類別
3、本節重點---抽象類別3.1、什麼是抽象類別
與java一樣,python也有抽象類別的概念但是同樣需要藉助模組實現,抽象類別是一個特殊的類,它的特殊之處在於只能被繼承,不能被執行個體化
3.2、為什麼要有抽象類別
如果說類是從一堆對象中抽取相同的內容而來的,那麼抽象類別就是從一堆類中抽取相同的內容而來的,內容包括資料屬性和函數屬性。
比如我們有香蕉的類,有蘋果的類,有桃子的類,從這些類抽取相同的內容就是水果這個抽象的類,你吃水果時,要麼是吃一個具體的香蕉,要麼是吃一個具體的桃子。。。。。。你永遠無法吃到一個叫做水果的東西。
從設計角度去看,如果類是從現實對象抽象而來的,那麼抽象類別就是基於類抽象而來的。
從實現角度來看,抽象類別與普通類的不同之處在於:抽象類別中只能有抽象方法(沒有實現功能),該類不能被執行個體化,只能被繼承,且子類必須實現抽象方法。這一點與介面有點類似,但其實是不同的,即將揭曉答案
4、在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)
4.1、抽象類別與介面
抽象類別的本質還是類,指的是一組類的相似性,包括資料屬性(如all_type)和函數屬性(如read、write),而介面只強調函數屬性的相似性。
抽象類別是一個介於類和介面直接的一個概念,同時具備類和介面的部分特性,可以用來實現歸一化設計
4.2、abc模組,Python 對於ABC的支援模組,定義了一個特殊的metaclass—— ABCMeta 還有一些裝飾器—— @abstractmethod 和 @abstarctproperty 。
import abcclass A(metaclass=abc.ABCmeta): @abc.abstractmethod# 定義抽象方法,無需實現功能 def read(self): pass @abc.abstarctproperty# 定義抽象屬性
4.3、例題
通過定義抽象類別,子類繼承抽象類別,把子類正常化,如果想調用抽象類別相同的函數,就必須和抽象類別保持一致,否則出錯
規範子類
import abcclass Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def run(self): pass @abc.abstractmethod def eat(self): passclass People(Animal): def run(self): print(‘people is walking‘) def eat(self): print(‘people is eating‘)class Dog(People): def run(self): print(‘dog is walking‘) def eat(self): print(‘dog is eating‘)class Pig(People): def run(self): print(‘pig is walking‘) def eat(self): print(‘pig is eating‘)people1 = People()dog1 = Dog()pig1 = Pig()people1.run()dog1.run()pig1.run()
4.4、抽象類別的說明
不能被執行個體化,只能被繼承:上題中Aminal是抽象類別 ,不能執行個體化 比如 animal=Aminal()
優點:正常化子類,降低使用的複雜度
8 python 抽象類別