多态性与鸭子类型讲述
多态与多态性
多态指的是一类事情有很多种形态,举例说明动物有很多种形态:猫、狗、猪
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方法,因此我们可以无需思考它们三者的详细有哪些类型的动物,而可以直接使用
>>> 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,无法实例化
但实际上大家完全能够不依赖于继承,只应该制造出外观和行为相似对象,一样能够完成不思考对象类型而使用对象,这恰好是Python崇尚的“鸭子类型”(ducktyping):“假如看起来像、叫声像并且走起路来像鸭子,那样它均是鸭子”。相较于继承的形式,鸭子类型在某种意义上完成了程序的松耦合度,如下所示
#二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系
class Txt: #Txt类有两个与文件类型同名的方法,即read和write def read(self): pass def write(self): pass class Disk: #Disk类也有两个与文件类型同名的方法:read和write def read(self): pass def write(self): pass

