在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,
新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印:
class Animal(object):
def run(self):
print('Anaimal is running ...')
当我们编写Dog和Cat类时可以直接从Animal继承
class Dog(Animal):
def run(self):
print('Dog is running ...')
def eat(self):
print('Eating meat...')#可以对子类添加代码
class Cat(Animal):
pass
#继承最大的好处就是,子类会继承父类的全部功能
a = Dog()
a.run()
当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()
b = Cat()
b.run()
#要理解什么是多态,我们首先要对数据类型再作一点说明
a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型
print(isinstance(a,list))
print(isinstance(b,Animal))
print(isinstance(c,Dog))
print(isinstance(c,Animal))
所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行:
新增一个Animal的子类,不必对run_twice()做任何修改,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态
def run_twice(a):
a.run()
run_twice(Animal())
run_twice(Dog())
class Tortoise(Animal):
def run(self):
print('Tortois is running ...')
run_twice(Tortoise())
对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:
class Timer(object):
def run(self):
print('Start...')
这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
版权声明:本文为a54288447原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。