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

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