本文是自己对廖大大的继承多态章节的总结,详细可直接看:
首先看看继承:
class Animal(object):
def run(self):
print("Animal is running...")
class Dog(Animal):
pass
class Cat(Animal):
pass
dog = Dog()
dog.run()
cat = Cat()
cat.run()
运行结果:
对子类同时增加run()方法:
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...")
dog = Dog()
dog.run()
cat = Cat()
cat.run()
运行结果:
当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。
多态的好处在于使用单一接口操作相似数据,下面增加一个run_twice函数:
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()
animal.run()
dog = Dog()
cat = Cat()
animal = Animal()
run_twice(dog)
run_twice(cat)
run_twice(animal)
运行结果:
同一个接口,因为所传参数不同,而干了不同的事。。传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思
静态语言 vs 动态语言
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:
class Timer(object):
def run(self):
print("Start...")
timer = Timer()
run_twice(timer)
增加上面代码并运行:
没有继承关系,同样可以由run_twice接口调用,这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。