三十二、Python类的继承与多继承详解

liftword2周前 (04-28)技术文章2

继承是面向对象的三大特征之一,也是实现软件复用的重要途径。Python中的继承机制是多继承机制,即一个子类可以同时有多个父类。

1.继承的语法

Python子类继承父类的语法是在定义子类时,将多个父类放在子类之后的圆括号里。语法格式如下:

class 子类名称(父类1,父类2,...):
    # 类的定义部分

如果在Python中定义一个类时未指定这个类的直接父类,则这个类默认继承object类。因此,object类是所有类的父类,要么是其直接父类,要么是其间接父类。

实现继承的类被称为子类,被继承的类被称为父类,也被称为基类、超类。父类和子类的关系,是一般和特殊的关系,是抽象和具体的关系。从子类角度来看,子类扩展了父类的功能。从父类角度来看,父类派生出了子类。

class People:
    # 定义类的基本属性
    name = ''
    age = ''
    # 定义类的私有属性
    __weight = 0

    # 定义类的构造方法
    def __init__(self, name, age, weight):
        self.name = name
        self.age = age
        self.__weight = weight
    # 定义成员方法
    def say(self):
        print(f'{self.name}说我今年{self.age}岁了')

    def walk(self):
        print(f'{self.name}会走路了')

# 定义学生继承自People类
class Student(People):
    # 定义学生类特有属性grade代表年级
    grade = ''
    # 定义学生类的构造方法
    def __init__(self, name, age, weight, grade):
        # 调用父类构造方法
        People.__init__(self,name, age, weight)
        self.grade = grade

    # 覆写父类的方法
    def say(self):
        print(f'{self.name}说我今年{self.age}岁了,我在读{self.grade}年级')

    # 定义成员方法
    def study(self):
        print(f'{self.name}说:好好学习,天天向上!')

# 实例化学生类
s1 = Student('关羽',35, 80,'三年级')
# 调用say()方法
s1.say() # 因为重写了父类方法,所以调用的是子类的say()方法
# 调用walk()方法,因为学生没有walk()方法,但是学生继承了People, 所以会调用父类的walk()方法
s1.walk()
# 调用study()方法,因为父类没有study, 子类定义了独有的study方法,会直接调用
s1.study()

2.多继承

绝大多数面向对象语言只支持单继承而不支持多继承,例如C++, Java等。Python虽然在语法上支持多继承,但通常建议如不是特殊情况,则尽量不要使用多继承,这样可以保证编程思路清晰。

当一个子类有多个直接父类时,该子类会继承得到所有父类的公有的方法。但是,如果直接继承的多个父类中有相同的方法时,Python会按照继承的父类的前后顺序,前面类中的方法会“屏蔽”后面父类中的同名方法。所以,对于子类和直接继承的父类的同名方法查找有顺序是:

子类 -> 直接子类(类1,类2,类3,...类n) 从左到右搜索,找到了就屏蔽后面的同名方法。
class Human:
    def __init__(self, name, age, gender, skin):
        self.name = name
        self.age = age
        self.gender = gender
        self.skin = skin

    def walk(self):
        print(f'{self.name}正在走路')

    def work(self):
        print(f'{self.name}工作了')
class Man(Human):
    def __init__(self, name, age, gender, skin, hair, mouth):
        Human.__init__(self, name, age, gender,skin)
        self.hair = hair
        self.mouth = mouth

    def work(self):
        print(f'我是男人,我要养家糊口')

    def game(self):
        print(f'我喜欢打游戏')

class Woman(Human):
    def __init__(self, name, age, gender, skin, hair, mouth):
        Human.__init__(self, name, age, gender, skin)
        self.hair = hair
        self.mouth = mouth

    def work(self):
        print(f'我是女人,我也要工作')

    def cook(self):
        print(f'我会做饭')


class Son(Man, Woman):
    def __init__(self, name, age, gender, skin, hair, mouth, grade):
        Man.__init__(self, name, age, gender,skin,hair,mouth)
        self.grade = grade

    def study(self):
        print('好好学习,天天向上')

# 实例化儿子类
s1 = Son('司马光',9,'男','白皮肤','黑头发','大嘴','三年级')
s1.study() # 调用自己独有方法
s1.work() # 父类Man和Woman都有的方法,从左到右找,找到后后面父类中的同名方法会隐藏
s1.game() # 父类Man的独有方法,继承过来
s1.cook() # 父类Woman的独有方法,继承过来
s1.walk() # 子类,直接父类都没有的方法,从父类的父类间接继承,因此继承具有传递性

3.方法重写

如果子类继承的父类的方法功能不能满足需求,可以在子类中重写父类中的同名方法:

class Animal:
    def say(self):
        print('动物在说话')

class Bird(Animal):
    def say(self):
        print('小鸟在唱歌')

class Wolf(Animal):
    def say(self):
        print('老狼在嚎叫')

# 实例化鸟的实例
b = Bird()
b.say() # 子类重写了父类方法

# 实例化狼的实例
w  = Wolf()
w.say() # 子类重写了父类方法

super(Bird, b).say() #用于调用父类中的方法
super(Wolf, w).say() #用于调用父类中的方法

下篇文章将详细介绍super关键字的使用

相关文章

Python | 多继承(python多继承父类参数问题)

在Python中,类可以继承自多个类。这被称为多继承。多继承是一种非常强大的概念,它允许我们将多个类的功能组合到一个类中。在本文中,我们将使用一个简单的示例来说明多继承的概念。假设我们正在编写一个图形...

python多继承的3C算法是什么?怎么用?

有很多地方都说python多继承的继承顺序,是按照深度遍历的方式,其实python多继承顺序的算法,不是严格意义上的深度遍历,而是基于深度遍历基础上优化出一种叫3C算法python多继承的深度遍历cl...

python之多态、继承、重写篇(python多态的作用特点)

# -*- coding: UTF-8 -*- class Animal: def run(self): print("动物会跑。。") def sl...

Python 中的继承和多态(python多继承的顺序)

Python 中的继承是什么?Python 中的继承是一个特性,允许一个类(子类)使用另一个类(父类)的属性和方法。这有助于我们重用代码并避免重复。思考一下亲子关系:孩子继承了父母的某些特征,但也可以...

python继承与多态-多继承二义性和弊端

在Python中,多继承是一种同时从多个父类继承属性和方法的机制。然而,多继承也可能导致二义性和带来一些弊端。下面我们来详细说明这些问题。二义性(Ambiguity)当一个类从多个父类继承了相同的方法...