26:多态性与鸭子类型
-
多态与多态性
1 多态与多态性
多态指的是一类事务有多种形态,比如动物有多种形态:猫、狗、猪
class Animal: #同一类事物:动物 def talk(self): pass class Cat(Animal): #动物的形态之一:猫 def talk(self): print('喵喵喵') class Dog(Animal): #动物的形态之二:狗 def talk(self): print('汪汪汪') class Pig(Animal): #动物的形态之三:猪 def talk(self): print('哼哼哼') #实例化得到三个对象 >>> cat=Cat() >>> dog=Dog() >>> pig=Pig() # 多态性指的是:可以在不用考虑对象具体类型的情况下而直接使用对象,这就需要在设计时,把对象的使用方法统一成一种
例如:
cat、dog、pig都是动物,但凡是动物肯定有talk方法, 于是我们可以不用考虑它们三者具体是什么类型的动物,而直接使用talk方法
>>> cat.talk() 喵喵喵 >>> dog.talk() 汪汪汪 >>> pig.talk() 哼哼哼
更进一步,我们可以定义一个统一的接口来使用
>>> def Talk(animal): ... animal.talk() ... >>> Talk(cat) 喵喵喵 >>> Talk(dog) 汪汪汪 >>> Talk(pig) 哼哼哼 python中一切皆对象,本身就支持多态性 # 我们可以在不考虑三者类型的情况下直接使用统计三个对象的长度 s.__len__() l.__len__() t.__len__() # Python内置了一个统一的接口 len(s) len(l) len(t)
多态性的好处在于增强了程序的灵活性和可扩展性
例如:
通过继承Animal类创建了一个新的类,实例化得到的对象obj,可以使用相同的方式去使用obj.talk()
>>> class Wolf(Animal): #动物的另外一种形态:狼 ... def talk(self): ... print('嗷...') ... >>> wolf=Wolf() # 实例出一匹狼 >>> wolf.talk() # 使用者根本无需关心wolf是什么类型而调用talk 嗷...
综上所述,可知:
'多态性的本质在于不同的类中定义有相同的方法名,这样我们就可以不考虑类,而统一用一种方法去使用对象,可以通过在父类中引入抽象类的概念来硬性限制子类必须有某些方法名'
import abc # 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化 class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法 def talk(self): # 抽象方法中无需实现具体的功能 pass class Cat(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准 def talk(self): pass cat=Cat() # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化