多态的概念程序员
多态指的是一类事物的多种形态,例如水有固态、液态、气态,动物有人、狗、猪,这是动物的不一样形态。可能你会领悟,人狗猪不是继承于动物类吗?没错,多态在程序中的表现形式就是依赖于继承
ide
多态性spa
那多态到底有什么特性呢?多态性指的是能够在不用考虑对象具体类型的前提下,直接使用对象下的方法,也就是说,继承同一个类的多个子类有相同的方法名,那么子类产生的对象就能够不用考虑具体的类型而直接调用对象的方法code
举一个例子,动物有人狗猪,动物都会叫,那么人狗猪也都会叫,只不过叫的方式不一样对象
class Animal: pass
class People(Animal): def speak(self): print('say hello') class Dog(Animal): def speak(self): print('汪汪汪') class Pig(Animal): def speak(self): print('哼哼哼') # peo、dog、pig都是动物, 只要是动物确定有speak方法 # 因而咱们能够不用考虑它们三者的具体是什么类型, 而直接使用
peo = People() dog1 = Dog() pig1 = Pig() peo.speak() dog1.speak() pig1.speak()
可是美中不足的是,若是如今人的叫不写成 speak ,写成 talk,那么便没法遵循父类的方法去实现多态性,若是这三个都想实现叫的功能,父类要有,子类也要有,这显然很麻烦,而且这样写不能对子类有个强制性的限制,这个限制是子类必须有一个叫的功能,这个功能是 speak。因而要写一个解决方案,强制子类遵循父类的标准,有一个 abc 的模块,能够实现这个功能blog
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass
class People(Animal): # def speak(self):
# print('say hello')
# 写成talk便会报错
def talk(self): print('say hello') class Dog(Animal): def speak(self): print('汪汪汪') class Pig(Animal): def speak(self): print('哼哼哼') peo = People() dog1 = Dog() pig1 = Pig() peo.speak() dog1.speak() pig1.speak() # 运行
TypeError: Can't instantiate abstract class People with abstract methods speak
鸭子类型继承
可是上面所说的这些并非 Python 所推崇的,Python 崇尚的是 “鸭子类型” ,即 “若是看起来像鸭子、叫声像鸭子并且走起路来也像鸭子,那么它就是鸭子”,字符串
Python 程序员一般根据这种行为来编写程序。例如,若是想编写现有对象的自定义版本,能够继承该对象,也能够建立一个外观和行为像,但与它无任何关系的全新对象,后者一般用于保存程序组件的解耦合度it
# 利用标准库中定义的各类‘与文件相似’的对象,尽管这些对象的工做方式像文件,但他们没有继承内置文件对象的方法 # 两者都像鸭子,两者看起来都像文件,于是就能够当文件同样去用
class TxtFile: def read(self): pass
def write(self): pass
class DiskFile: def read(self): pass
def write(self): pass
# 例2:其实你们一直在享受着多态性带来的好处,好比Python的序列类型有多种形态:字符串,列表,元组,多态性体现以下 # str,list,tuple都是序列类型
s=str('hello') l=list([1,2,3]) t=tuple((4,5,6)) # 咱们能够在不考虑三者类型的前提下使用s,l,t
s.__len__() l.__len__() t.__len__() len(s) len(l) len(t)