一 : 初识继承

  继承是为了在在一个类中方便的使用另一个类中的内容.

class Animal:
    breath = '呼吸'

    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print(self)
        print('动物需要进食....')


class Person(Animal):  
    pass

  这段代码中,类Person继承了类Animal,那么我们把类Person称作子类/派生类,把类Animal称作父类/基类/超类. 在python3.x中,所有类默认继承了objec类,如果在定义类的时候不写括号或者括号内没有内容,默认继承objec类.

  子类可以直接使用父类中的内容,比如这个Person类,其中什么都没有,但是在它实例化的时候,会调用父类中的__init__()函数,必须要传入name/sex/age三个参数

p1 = Person('alex', 'laddyboy', 1000)
print(p1.__dict__) # {'name': 'alex', 'sex': 'laddyboy', 'age': 1000}
p1.eat() #<__main__.Person object at 0x0000022FAC4A5390> 动物需要进食....
print(p1.breath) # 呼吸
print(p1) # <__main__.Person object at 0x00000195C7FEB390>

  可以看到,当我们调用父类的eat方法,打印self的结果是子类的对象,和打印p1的地址一致,可以通过子类的对象获得父类中的内容.这是因为子类中存在一个指向父类的指针,当调用子类的内容的时候,如果不存在,就会通过这个指针向父类中寻找.原理与类和对象空间的关系相似.

  可以直接在子类中调用父类中的内容,可以通过两种方法办到,其一是直接用父类名 . 变量名/方法名  的方式,其二是 用 super() . 变量名/方法名 的方式,推荐用第二种方法,因为python是支持多继承的,这种方法泛用性更高.

class Animal:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self, a1):
        print('%s吃%s' % (self.name, a1))

    def drink(self):
        print('%s喝东西' % (self.name))


class Cat(Animal):

    def miaow(self):
        print('喵喵叫')
    def drink(self):  # 只执行自己类中的方法
        print('类Cat中的drink')


class Brid(Animal):

    def __init__(self, name, sex, age, wing):
        # Animal.__init__(self, name, sex, age) 这是第一种方法
        super().__init__(name, sex, age)  #  第二种方法(推荐) super(Brid,self).__init__(name,sex,age)这是完整版的调用方式,括号里的父类名和self是可以省略的
        self.wing = wing

    def bark(self):
        print('嗷嗷叫')

    def eat(self, argv):
        super().eat(argv)
        print('鸟吃虫子...')


c1 = Cat('LiFuGui', '雄性', 2) #实例化一只猫
c1.drink() # 调用dring()方法, 此时子类和父类中都有名为dring的方法  打印结果 : 类Cat中的drink
c1.eat('耗子') # 子类中没有eat方法,于是调用父类中的eat方法  打印结果:LiFuGui吃耗子

二 : 多继承

  一条线的继承很好理解,父类中没有的内容会向父类的父类中寻找,代码如下

class A:
    def func(self):
        print('IN A')

class B(A):
    pass
    # def func(self):
    #     print('IN B')

class C(B):
    pass

c1= C()
c1.func() # IN A

  麻烦的是一个类同时有多个父类:

class A:
    def func(self):
        print('IN A')

class B(A):
    pass
    # def func(self):
    #     print('IN B')

class C(A):
    pass
    # def func(self):
    #     print('IN C')

class D(B):
    pass
    # def func(self):
    #     print('IN D')

class E(C):
    pass
    # def func(self):
    #     print('IN E')

class F(D,E):
    pass
    # def func(self):
    #     print('IN F')

f1 = F()
f1.func()

  通过mro函数可以获得一个类的继承路线,当它向父类寻找一个内容的时候,会遵循这个顺序

print(F.mro()) #[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

  这个顺序是通过C3算法得到的,我们不通过mro()函数,可以通过merge list和拓扑排序两种方式获得这个顺序.因为这两种方式太复杂,再次不再描述.