python之抽象類


1什么是抽象類

與java一樣,python也有抽象類的概念但是同樣需要借助模塊實現,抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被實例化

2為什么要有抽象類

如果說類是從一堆對象中抽取相同的內容而來的,那么抽象類就是從一堆類中抽取相同的內容而來的,內容包括數據屬性和函數屬性。

 

比如我們有香蕉的類,有蘋果的類,有桃子的類,從這些類抽取相同的內容就是水果這個抽象的類,你吃水果時,要么是吃一個具體的香蕉,要么是吃一個具體的桃子。。。。。。你永遠無法吃到一個叫做水果的東西。

從設計角度去看,如果類是從現實對象抽象而來的,那么抽象類就是基於類抽象而來的。

從實現角度來看,抽象類與普通類的不同之處在於:抽象類中只能有抽象方法(沒有實現功能),該類不能被實例化,只能被繼承,且子類必須實現抽象方法。

 

3在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抽象類與接口

抽象類的本質還是類,指的是一組類的相似性,包括數據屬性(如all_type)和函數屬性(如read、write),而接口只強調函數屬性的相似性。

抽象類是一個介於類和接口直接的一個概念,同時具備類和接口的部分特性,可以用來實現歸一化設計

 

5繼承原理

class A(object):

    def test(self):

        print('from A')

 

class B(A):

    def test(self):

        print('from B')

 

class C(A):

    def test(self):

        print('from C')

 

class D(B):

    def test(self):

        print('from D')

 

class E(C):

    def test(self):

        print('from E')

 

class F(D,E):

    # def test(self):

    #     print('from F')

    pass

f1=F()

f1.test()

print(F.__mro__) #只有新式才有這個屬性可以查看線性列表,經典類沒有這個屬性

 

#新式類繼承順序:F->D->B->E->C->A

#經典類繼承順序:F->D->B->A->E->C

#python3中統一都是新式類

#pyhon2中才分新式類與經典類

  

 

對於你定義的每一個類,python會計算出一個方法解析順序(MRO)列表,這個MRO列表就是一個簡單的所有基類的線性順序列表

>>> F.mro() #等同於F.__mro__

[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

  

 

為了實現繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類為止。

而這個MRO列表的構造是通過一個C3線性化算法來實現的。我們不去深究這個算法的數學原理,它實際上就是合並所有父類的MRO列表並遵循如下三條准則:

1.子類會先於父類被檢查

2.多個父類會根據它們在列表中的順序被檢查

3.如果對下一個類存在兩個合法的選擇,選擇第一個父類

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM