第11章-抽象类
ABC类
python中并没有提供抽象类与抽象方法,
但是提供了内置模块abc(abstract base class)来模拟实现抽象类。
可以通过abc将基类声明为抽象类的方式,然后注册具体类作为这个基类的实现。
假设我们在写一个关于动物的代码。涉及到的动物有鸟,狗,牛。
首先鸟,狗,牛都是属于动物的。既然是动物那么肯定需要吃饭,发出声音。
但是具体到鸟,狗,牛来说吃饭和声音肯定是不同的。
需要具体去实现鸟,狗,牛吃饭和声音的代码。
概括一下抽象基类的作用:定义一些共同事物的规则和行为
例子:
class Animal(object):
def eat(self):
raise NotImplementedError
def voice(self):
raise NotImplementedError
class Dog(Animal):
def voice(self):
print('wow....')
class Bird(Animal):
def voice(self):
print('jiji....')
class Cow(Animal):
def voice(self):
print('Oh.....')
if __name__ == "__main__":
d = Dog()
d.voice()
d.eat() # raise NotImplementedError
这样实现有个缺点,就是只有子类调用eat方法的时候才会报错。
子类是可以正常实例化的。
但是你能够想象鸟,狗,牛不会吃饭么? 如果不会吃饭那肯定不算是动物了。
所以正常的实现应该是如果没有实现eat方法,实例化就应该是失败的。
那么这里就要用到抽象基类的一般使用方法.
import abc
class Animal(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def eat(self):
return
@abc.abstractmethod
def voice(self):
return
class Dog(Animal):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
class Bird(Animal):
def voice(self):
print('jiji....')
def eat(self):
print("Bird eat...")
class Cow(Animal):
def voice(self):
print('Oh.....')
def eat(self):
print("Cow eat...")
if __name__ == "__main__":
d = Dog()
b = Bird()
c = Cow()
d.voice()
d.eat()
b.voice()
b.eat()
c.voice()
c.eat()
返回结果:
wow....
Dog eat...
jiji....
Bird eat...
Oh.....
Cow eat...
使用注册的方式:
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def eat(self):
return
@abstractmethod
def voice(self):
return
class Dog(object):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
# 使用注册方式,必须两个方法都要写,否则会报错
Animal.register(Dog)
if __name__ == "__main__":
d = Dog()
d.voice()
d.eat()
继承和注册这两种方法有什么区别呢?
animals.py
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def eat(self):
return
@abstractmethod
def voice(self):
return
sub_class.py
from animals import Animal
class Dog(Animal):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
print('subclass=', issubclass(Dog, Animal))
print('Instance=', isinstance(Dog(), Animal))
abc_register.py
from animals import Animal
class Dog(object):
def voice(self):
print('wow....')
def eat(self):
print("Dog eat...")
Animal.register(Dog)
print('subclass=', issubclass(Dog, Animal))
print('Instance=', isinstance(Dog(), Animal))
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。