abc模块
(抽象类基类,Abstract Base Classes)中的两个工具abstractmethod, ABCMeta,详情如下:工具 | 说明 |
---|---|
abstractmethod | 抽象类的装饰器,接口类中的接口需要使用此装饰器 |
ABCMeta | 抽象类元类 |
接下来我们来定义一个图形的接口类GraphicRule和子类Rectangle
,提供两个接口,如下:
接口 | 说明 |
---|---|
area | 图形的面积 |
perimeter | 图形的周长 |
接口类仅提供接口的约束,不实现其接口功能,由其子类的矩形类Rectangle
实现,如果子类Rectangle不实现接口类GraphicRule中所有的接口,即area和perimeter,在实例对象的时候,会抛出异常
from abc import ABCMeta,abstractmethod #从abc模块中导入ABCMeta这个元类
class GraphicRule(metaclass=ABCMeta): #接口类:
@abstractmethod
def area(self,length,width):
pass
@abstractmethod
def perimeter(self,length,width):
pass
class Rectangle(GraphicRule): #子类继承了接口类后,才可以实现接口类中指定好的规范
def __init__(self,length,width):
self.length = length
self.width = width
#对父类这个接口类中指定好的规范进行实现
def area(self,length,width):
return length * width
def perimeter(self,length,width):
return (length+width)*2
r = Rectangle(2,3)
r.area(2,3)
from abc import ABCMeta,abstractmethod #从abc模块中导入ABCMeta这个元类
class GraphicRule(metaclass=ABCMeta): #接口类:
@abstractmethod
def area(self,length,width):
pass
@abstractmethod
def perimeter(self,length,width):
pass
class Rectangle(GraphicRule): #子类继承了接口类后,才可以实现接口类中指定好的规范
def __init__(self,length,width):
self.length = length
self.width = width
#对父类这个接口类中指定好的规范进行实现
def area(self,length,width):
return length * width
def perimeter(self,length,width):
return (length+width)*2
r = Rectangle(2,3)
r.area(2,3)
from abc import abstractmethod, ABCMeta
class Fruit(metaclass=ABCMeta):
@abstractmethod
def func1(self):
pass
@abstractmethod
def func2(self):
pass
#可以定义正常方法
def normalFunc(self):
print('i am nomal func!')
class Apple(Fruit):
def func1(self):
print('i am func1')
def func2(self):
print('i am func2')
Apple().normalFunc()
先看下面的代码:
pass
狗、猫、猪都继承了动物类,并各自重写了kind方法。show_kind()函数接收一个animal参数,并调用它的kind方法。可以看出,无论我们给animal传递的是狗、猫还是猪,都能正确的调用相应的方法,打印对应的信息。这就是多态。
实际上,由于Python的动态语言特性,传递给函数show_kind()的参数animal可以是 任何的类型,只要它有一个kind()的方法即可。动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。