Skip to content

多继承

专业术语

Tiger 类是 Animal 类的子类,Animal 类是 Tiger 类的父类,

Tiger 类是 Animal 类的派生类,Animal 类是 Tiger 类的基类,Tiger 类从 Animal 类派生

语法:

python
class 子类名(父类名1, 父类名2...)
    pass

多继承案例

子类可以同时继承多个父类,享受父类封装好的方法与属性。

python
"""  
    定义动物类(Animal)一个动物类  
        属性:name、high、weight  
        方法:eat  
  
    定义老虎类(Tiger)  
        属性:name、high、weight  
        方法:eat、bark、tiger_skill  
  
    定义狮子类(Lion)  
        属性:name、high、weight  
        方法:eat、bark、lion_skill  
  
    定义狮虎兽(Liger)  
        属性:name、high、weight  
        方法:eat、bark、tiger_skill, lion_skill  
"""


class Animal(object):
    def __init__(self, name, high, weight):
        self.name = name
        self.high = high
        self.weight = weight

        # 动物默认吃东西的声音  

    def eat(self):
        print(f'{self.name} 正在吃东西')


class Tiger(Animal):
    def __init__(self, name, high, weight):
        # 相当于调用了父类的初始化放在,在父类的init方法中绑定 name, high, weight        
        super().__init__(name, high, weight)

    def bark(self):
        print(f'{self.name} 正在嗷呜叫~~~')

    def tiger_skill(self):
        print(f'来自丛林之王 {self.name} 必杀技')

    def eat(self):
        print(f'{self.name} 正在吃东西, 发出咔咔咔的声音')


class Lion(Animal):
    def __init__(self, name, high, weight):
        super().__init__(name, high, weight)

    def bark(self):
        print(f'{self.name} 正在吼吼叫~~~')

    def lion_skill(self):
        print(f'来自草原之王 {self.name} 必杀技')

    # 狮虎兽该怎么继承  


class Liger(Lion, Tiger):
    def __init__(self, name, high, weight):
        super().__init__(name, high, weight)

    # def bark(self):  
    #     print(f'{self.name} 正喵喵叫~~~')  


liger = Liger('狮虎兽壹号', 1.3, 60)
liger.tiger_skill()
liger.lion_skill()

liger.bark()

继承的传递性

C 类从 B 类继承,B 类又从 A 类继承

那么 C 类就具有 B 类和 A 类的所有属性和方法

子类拥有父类以及父类的父类中封装的所有属性和方法

编写 Tiger 类与 Animal 类

python
class Animal(object):
    """动物类"""

    def __init__(self, name, high, weight):
        self.name = name
        self.high = high
        self.weight = weight

    def eat(self):
        return self.name + ' 正在吃东西'


class Cat:
    """猫科类"""

    def __init__(self, name, color):
        self.name = name
        self.color = color


class Tiger(Animal, Cat):
    def __init__(self, name, high, weight):
        super().__init__(name, high, weight)


"""先继承自 (Cat, Animal)"""  # tiger = Tiger('虎大', '老虎')  
# print(tiger.name)  
# print(tiger.color)  

"""然后继承自 (Animal, Cat)"""  # 对比分析区别  
tiger2 = Tiger('虎二', '250 cm', '360 kg')
print(tiger2.eat())
print(tiger2.name)
print(tiger2.high)
print(tiger2.weight)

MRO搜索顺序

  • Python 中针对 类 提供了一个 内置属性 __mro__ 可以查看 方法 搜索顺序
  • MRO 是 method resolution order,主要用于 在多继承时判断 方法、属性 的调用 路径
python
print(C.__mro__)

输出结果

(<class '__main__.C'>, < class '__main__.A' >, < class '__main__.B' >, < class 'object' > )
  • 在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的
  • 如果在当前类中 找到方法,就直接执行,不再搜索
  • 如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索
  • 如果找到最后一个类,还没有找到方法,程序报错

使用注意事项

如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢?

提示:开发时,应该尽量避免这种容易产生混淆的情况! —— 如果父类之间存在同名的属性或者方法,应该尽量避免使用多继承