在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...')

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