Python-面向对象编程之多态
一、基本概念
-
什么是多态?
多态:同一事物有多种形态
比如动物有多种形态:猫、狗、猪
class Animal: # 同一类事物:动物 def talk(self): print('动物电码,滴滴哒哒') 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 = Cat() dog = Dog() pig = Pig() cat.talk() dog.talk() pig.talk()
更进一步,我们可以定义一个统一的接口来使用:
def animal_talk(animal): animal.talk() cat = Cat() dog = Dog() pig = Pig() animal_talk(cat) animal_talk(dog) animal_talk(pig)
其实我们一直都在使用多态的概念:
比如字符串、列表、字典等对象都具有
.__len__()
方法print('hello'.__len__()) print([1, 2, 3].__len__()) print({'a': 1, 'b': 2}.__len__())
更进一步,可以定义一个统一的接口来使用:
def my_len(val): return val.__len__() print(my_len('hello')) print(my_len([1, 2, 3])) print(my_len({'a': 1, 'b': 2}))
其实这就是:
print(len('hello')) print(len([1, 2, 3])) print(len({'a': 1, 'b': 2}))
个人对继承类多态的理解:子类们继承父类,再统一子类方法接口,实现拿来即用,不再通过调用使用。
二、鸭子类型
python中更为推崇的多态是鸭子类型
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。这个概念的名字来源于由[James Whitcomb Riley](https://baike.baidu.com/item/James Whitcomb Riley)提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
——百度百科:鸭子类型
即我们并不关心对象是什么类型,究竟是不是鸭子,仅仅关心行为。比如迭代器,任何实现了__iter__
和__next__
方法的对象都可称之为迭代器,但对象本身是什么类型不受限制,可以自定义为任何类。
个人对鸭子类多态的理解:
丧心病狂到拿方法作为参照来把一群类统一接口,比如汽车能跑,人也能跑,而且都是在地上跑,所以定义一个统一的“跑”接口,不管是人还是车扔进去都是能跑。换言之,按照人的思维来对类进行划分、统一接口,前提是这类对象有一种相同物理(生物)特征。比如动物分猫狗猪,这种分类思维固化在我们的脑子里。现在这种鸭子类型,相当于把所有具有相同“方法(功能、行为)”的对象打包出一个共同接口,而并不关心相同行为后面不同的对象是什么牛鬼蛇神。
# 超人 飞机 鸟
# 按照鸭子类型思想:
class 超人:
def fly(self):
print('飞飞飞')
class 飞机:
def fly(self):
print('飞飞飞')
class 鸟:
def fly(self):
print('飞飞飞')
def fly(obj):
obj.fly()
# 超人 飞机 鸟
# 按照常规思想:
class 动物:
def fly(self):
print('飞飞飞')
class 超人(动物):
pass
class 鸟(动物):
pass
class 飞机:
def fly(self):
print('飞飞飞')
obj = 超人()
def fly(obj):
obj.fly()
fly(obj)
嗯,还是很玄乎。