python 面向对象之多态
多态是什么?
用一句话来概括下,多态就是同一操作(方法)作用于不同的对象时,可以有不同的解释,产生不同的执行结果。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017/12/26 0026 15:18 # @Author : ming class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def who(self): return 'I am a Person, my name is %s' % self.name class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score def who(self): return 'I am a Student, my name is %s' % self.name class Teacher(Person): def __init__(self, name, gender, course): super(Teacher, self).__init__(name, gender) self.course = course def who(self): return 'I am a Teacher, my name is %s' % self.name def run(x): print(x.who()) a = Person("keke", "Male") b = Student("Coke", "Male", 98) c = Teacher("Jone", "Female", "Chinese") run(a) run(b) run(c)
在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:
I am a Person, my name is keke I am a Student, my name is Coke I am a Teacher, my name is Jone
这种行为称为多态。也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 who()方法以及从 Person继承的 who方法,但调用 s.who()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。
由于Python是动态语言,所以,传递给函数 who(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个who()的方法即可。
在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行,如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017/12/26 0026 15:18 # @Author : ming class Animal: 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() animal.run() a = Animal() d = Dog() c = Cat() print('a is Animal?', isinstance(a, Animal)) print('a is Dog?', isinstance(a, Dog)) print('a is Cat?', isinstance(a, Cat)) print('d is Animal?', isinstance(d, Animal)) print('d is Dog?', isinstance(d, Dog)) print('d is Cat?', isinstance(d, Cat)) run_twice(c)
a is Animal? True a is Dog? False a is Cat? False d is Animal? True d is Dog? True d is Cat? False Cat is running... Cat is running...