在面向对象编程中,接口的多种不一样的实现方式即为多态。多态的做用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。python
多态的目的就是实现接口重用。编程
多态指的是一类事物有多种形态。好比动物有多种形态:人、狗、猪。ide
import abc #利用abc模块实现抽象类 class Animal(metaclass=abc.ABCMeta): # 相似接口,只定义规范,不实现具体的代码 @abc.abstractclassmethod def talk(self): pass class People(Animal): # 动物形态之一:人 def talk(self): print('people is talking') class Pig(Animal): # 动物形态之二:猪 def talk(self): print('Pig is talking') class Dog(Animal): # 动物形态之三:狗 def talk(self): print('Dog is talking')
多态性指在不考虑实例类型的状况下使用实例,多态性分为静态多态性和动态多态性。函数
静态多态性:就是在系统编译期间就能够肯定程序执行到这里将要执行哪一个函数spa
动态多态性:则是利用虚函数实现了运行时的多态,也就是说在系统编译的时候并不知道程序将要调用哪个函数,只有在运行到这里的时候才能肯定接下来会跳转到哪个函数的栈帧。以下所示:code
peo1 = People() pig1 = Pig() dog1 = Dog() # 调用方法不用考虑三者具体是什么类型直接使用,这种就是动态多态性 # peo1.talk() # pig1.talk() # dog1.talk() #更进一步,咱们能够定义一个统一的接口来使用 def func(animal): animal.talk() func(peo1) func(pig1) func(dog1)
由上例能够看出,python自己就是支持多态性的。对象
(1)增长程序的灵活性blog
以不变应万变,不管对象变幻无穷,使用者都是同一种形式去调用继承
(2)增长程序的扩展性接口
经过继承animal类建立一个新类,使用者能够不改变本身的代码,依然用func(animal)调用
>>> class Cat(Animal): #属于动物的另一种形态:猫 ... def talk(self): ... print('say miao') ... >>> def func(animal): #对于使用者来讲,本身的代码根本无需改动 ... animal.talk() ... >>> cat1=Cat() #实例出一只猫 >>> func(cat1) #甚至连调用方式也无需改变,就能调用猫的talk功能 say miao ''' 这样咱们新增了一个形态Cat,由Cat类产生的实例cat1,使用者能够在彻底不须要修改本身代码的状况下。
使用和人、狗、猪同样的方式调用cat1的talk方法,即func(cat1) '''
什么是鸭子类型(Duck Typing)?鸭子类型可解释为,若是一只动物,走起来像鸭子或者叫起来像鸭子,就能够把它看成鸭子。
python崇尚一种鸭子类型,类与类之间不用共同继承一个父类,只须要将它们作得像一种事物便可。
例如,若是想编写现有对象的自定义版本。
一、能够继承该对象
二、能够建立一个外观和行为像,但与它无任何关系的全新对象(一般用于保存程序组件的松耦合度)
例1:利用标准库中定义的各类‘与文件相似’的对象,尽管这些对象的工做方式像文件,但他们没有继承内置文件对象的方法
class File: def read(self): pass def write(self): pass class Disk: def read(self): print('disk read') def write(self): print('disk write') class Text: def read(self): print('text read') def write(self): print('text write') disk = Disk() text = Text() disk.read() disk.write() text.read() text.write() """ disk read disk write text read text write """
例2:序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系
# 序列类型:列表list、元组tuple、字符串str l = list([1, 2, 3]) t = tuple(('a', 'b')) s = str('hello') print(l.__len__()) # 3 print(t.__len__()) # 2 print(s.__len__()) # 5