python中面向对象中的多态

多态:是面向对象思想的特征之一(特征还包括:封装,继承/派生),首先需要明白的是多态并不是只在类中有所体现,多态思想体现在python整个这门语言中。

比如:

运算符多态:

?
1
2
3
4
5
6
a = 34
b = 57
print (a + b)
a = "世界"
b = "你好"
print (a + b)
我们不知道+法运算符左右两个变量是什么类型,当我们给的是int类型时,它就进行加法运算。当我们给的是字符串类型时,它就返回的是两个字符串拼接的结果。也就是根据变量类型的不同,表现不同的形态。
类中 方法的多态:

class Animal(object):
    def run(self):
        print('Animal is running...')

class Dog(Animal): def run(self): print('Dog is running...')class Cat(Animal): def run(self): print('Cat is running...')
def run_twice(animal): animal.run() run_twice(Animal())-------Animal is running... run_twice(Dog())----------Dog is running...
run_twice(Cat())----------Cat is running...
不管animal是什么类型,只要有run()这个方法就可以调用(补充:当定义一个类时,其实就是定义了一种数据类型,可以用isinstance()来判断是否为某个数据类型,Dog既是Dog这种数据类型,同时也是Animal这种数据类型 但是Dog是其确切的数据类型)

方法的调用与对象相关,不与类型相关


在继承/派生关系的类中,调用对象的方法时,总是先查找其自身定义的方法,如果自身没有的话,则顺着继承链继续查找,直到在其父类中找到为止

用更为精简的语言形容多态在继承/派生类中的语言:

方法的调用将作用在类的确切类型上

Python中支持多态是因为Python是动态语言(调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:

class Timer(object):
    def run(self):
        print('Start...')

这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。



你可能感兴趣的:(python中面向对象中的多态)