Python3之接口類(InterfaceClass)淺談

日期:2020年3月14日
作者:Commas
註釋:學習就是爲了忘記,什麼是接口類,怎麼將方法變爲屬性;
如果您想了解更多有關Python的知識,那麼請點《我的Python淺談系列目錄》



一、接口類的定義與作用

接口類實際上就是一個規範子類的類,只不過這個類與別的類不太一樣,接口(內部的方法)本身不實現,子類繼承接口類,子類需要實現接口的功能,否則無法正常工作。那麼作用也毋庸置疑,就是規範好子類的接口。
定義一個接口類,我們需要abc模塊(抽象類基類,Abstract Base Classes)中的兩個工具abstractmethod, ABCMeta,詳情如下:

工具 說明
abstractmethod 抽象類的裝飾器,接口類中的接口需要使用此裝飾器
ABCMeta 抽象類元類
from abc import abstractmethod, ABCMeta


def 接口類名(metaclass=ABCMeta):
	"""定義您的接口類"""

	@abstractmethod
    def 方法1(self):
        """定義接口名,但不需要實現其功能,由繼承此類的子類實現"""
        pass

	@abstractmethod
    def 方法2(self):
        """定義接口名,但不需要實現其功能,由繼承此類的子類實現"""
        pass

二、圖形的接口類示例

接下來我們來定義一個圖形的接口類GraphicRule,提供兩個接口,如下:

接口 說明
area 圖形的面積
perimeter 圖形的周長

接口類僅提供接口名的約束,不實現其接口功能,由其子類的矩形類Rectangle實現,如果子類Rectangle不實現接口類GraphicRule中所有的接口,即area和perimeter,在實例對象的時候,會拋出異常,如我們不實現接口perimeter,將會得到以下異常:

TypeError: Can't instantiate abstract class Rectangle with abstract methods perimeter

在我們看到這個異常的時候,我們就知道我們還有什麼接口沒有實現,異常的解決還不是so easy的事情,完整的示例代碼如下:

from abc import abstractmethod, ABCMeta


class GraphicRule(metaclass=ABCMeta):
    """圖形接口類"""

    @abstractmethod
    def area(self):
        """面積"""
        pass

    @abstractmethod
    def perimeter(self):
        """周長"""
        pass


class Rectangle(GraphicRule):
    """矩形類"""
    def __init__(self, b, h):
        self.b = b
        self.h = h

    def area(self):
        return self.b*self.h

    def perimeter(self):
        return (self.b+self.h)*2

# 實例矩形類的一個對象
rect1 = Rectangle(3, 7)
print("矩形面積:{}".format(rect1.area()))
print("矩形周長:{}".format(rect1.perimeter()))

# =======控制檯輸出結果=======
矩形面積:21
矩形周長:20

三、@property讓方法秒變“屬性”

上面我們已經完成了一個接口類的定義以及使用接口類,但是看着那兩個接口的調用,還是感覺有點彆扭。面積area與周長perimeter,在我們的認知中,應該屬於一個對象的屬性纔對;而獲得面積get_area與獲得周長get_perimeter,看上起更像一個對象的方法。那麼我們有沒有可能將方法轉爲屬性呢?答案是有的,使用@property裝飾器,讓方法秒變屬性,如下:

@property
def 方法名(self):
	pass

所以示例可修改爲:

from abc import abstractmethod, ABCMeta


class GraphicRule(metaclass=ABCMeta):
    """圖形接口類"""

    @abstractmethod
    def area(self):
        """面積"""
        pass

    @abstractmethod
    def perimeter(self):
        """周長"""
        pass


class Rectangle(GraphicRule):
    """矩形類"""
    def __init__(self, b, h):
        self.b = b
        self.h = h

    @property
    def area(self):
        return self.b*self.h

    @property
    def perimeter(self):
        return (self.b+self.h)*2


rect1 = Rectangle(3, 7)
# (1)註釋以下的方法調用
# print("矩形面積:{}".format(rect1.area()))
# print("矩形周長:{}".format(rect1.perimeter()))
# (2)屬性調用
print("矩形面積:{}".format(rect1.area))
print("矩形周長:{}".format(rect1.perimeter))

# =======控制檯輸出結果=======
矩形面積:21
矩形周長:20

版權聲明:本文爲博主原創文章,如需轉載,請給出:
原文鏈接:https://blog.csdn.net/qq_35844043/article/details/104862886

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章