• 2.1.4 面向对象:类的继承(Python)


    本文来自异想之旅公开发布的Python教程,原文地址:https://www.yuque.com/yxzl/python

    类的继承

    在前面的示例中,我们一直在使用Student这个类。现在我们的需求升级了,不但需要在Student中加入更多的属性和方法,还需要新增一个Teacher类。按照之前的思路,我们可以这么书写:

    class Student:
        name = ''
        age = 0
        gender = ''
        grade = 1
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_hello(self):
            print('Hello!')
    
        def introduction(self):
            print('Hello, I am student', self.name)
    
    
    class Teacher:
        name = ''
        age = 0
        gender = ''
        subject = ''
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_hello(self):
            print('Hello!')
    
        def introduction(self):
            print('Hello, I am teacher', self.name)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    我们发现,这两个类有着许多十分相似的地方:name``age``gender三个相容的属性,__init__``say_hello两个相同的方法,以及两个相似的introduction方法。

    我们考虑定义一个类People,它将实现StudentTeacher共有的部分:

    class Person:
        name = ''
        age = 0
        gender = ''
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_hello(self):
            print('Hello!')
    
    
    class Student(Person):
        grade = 1
    
        def introduction(self):
            print('Hello, I am student', self.name)
    
    
    class Teacher(Person):
        subject = ''
    
        def introduction(self):
            print('Hello, I am teacher', self.name)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    看,将公共部分抽离后代码简短了一些,也变得更加直观了。现在我们希望我们在定义StudentTeacher时可以直接将People的属性和方法也“据为己有”——即继承Person已有的属性和方法,加上自己新增的,成为一个新的类。

    我们在后面跟上一个括号,括号中写上要被继承的类。这一过程便被称为类的继承Person被称作StudentTeacher父类,而StudentTeacher分别为Person子类。一个类的子类和父类都可以有多个

    在上面的代码后面执行这段代码,会得到这样的输出:

    student = Student('小明', 10, '男')
    student.say_hello()  # Hello
    student.introduction()  # Hello, I am student 小明
    
    teacher = Teacher('小红', 20, '女')
    teacher.say_hello()  # Hello
    teacher.introduction()  # Hello, I am teacher 小红
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    方法重写

    现在要对Teacher类的say_hello方法进行更改:将输出的内容改为'Hello students!'

    我们发现,这样一来Teacher中的say_hello方法和Student中不一样了,而继承的部分一定是统一的才行。我们要将Person中的say_hello方法重新放回两个类中去分别定义吗?

    自然,对于这个只有TeacherStudent两个类的示例,这样写也是可以的,但是假设我们还有Worker等等一些其它的、也同时都继承自Person的类,这样操作就太麻烦了。我们可以对类的方法进行重写

    class Person:
        name = ''
        age = 0
        gender = ''
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_hello(self):
            print('Hello!')
    
    
    class Student(Person):
        grade = 1
    
        def introduction(self):
            print('Hello, I am student', self.name)
    
    
    class Teacher(Person):
        subject = ''
    
        def say_hello(self):
            print('Hello students!')
    
        def introduction(self):
            print('Hello, I am teacher', self.name)
    
    
    student = Student('小明', 10, '男')
    student.say_hello()  # Hello
    student.introduction()  # Hello, I am student 小明
    
    teacher = Teacher('小红', 20, '女')
    teacher.say_hello()  # Hello students!
    teacher.introduction()  # Hello, I am teacher 小红
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    我们在子类Teahcer中定义了一个和父类中方法重名的方法,Python 会自动使用子类中的定义而抛弃父类中的定义。

    super()

    基本用例

    一个类可以通过 super() 调用其继承的类的函数:

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            
    class Student(Person):
        def __init__(self, name, age, grade):
            self.grade = grade
            super().__init__(name, age)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    高级使用

    super() 可以传入两个参数,分别代表从哪个类向后找和传入的 self

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            
    class Student(Person):
        def __init__(self, name, age, grade):
            self.grade = grade
            super().__init__(name, age)
            # 上面一行语句等价于
            super(Student, self).__init__(name, age)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    比如我们有Person继承AnimalStudent继承Person,想要在Student里调用Animal的函数,可以如下使用:

    class Animal:
        def __init__(self, age):
            self.age = age
    
    class Person(Animal):
        def __init__(self, name):
            self.name = name
            
    class Student(Person):
        def __init__(self, name, age, grade):
            self.grade = grade
            super(Student, self).__init__(name)
            super(Person, self).__init__(age)
            
    # 当然,上面只是一个演示,实际上这个例子应该这样写:
    
    class Animal:
        def __init__(self, age):
            self.age = age
    
    class Person(Animal):
        def __init__(self, name, age):
            self.name = name
            super().__init__(age)
            
    class Student(Person):
        def __init__(self, name, age, grade):
            self.grade = grade
            super().__init__(name, age)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    super的全局使用

    除了类的方法内部,在 Python 代码的任意位置都可以调用super()函数。只不过,在方法之外的位置使用必须完整传递两个参数

    class People:
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_hello(self):
            print('Hello!')
    
    
    class Teacher(People):
        subject = ''
    
        def say_hello(self):
            print('Hello students!')
    
    
    teacher = Teacher('小红', 20, '女')
    teacher.say_hello()  # Hello students!
    super(Teacher, teacher).say_hello()  # Hello!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    音视频流媒体开发难以学习?今天教你如何“丝滑”入门
    什么是跨域?及7种跨域解决方法
    性能测试_JMeter中你可能会忽略的细节点-2
    偶数科技发布 OushuDB 5.0,多活主节点、多虚拟集群等特性完美支持实时湖仓一体
    基于SpringBoot的超市管理系统
    Java项目源码下载S2SH基于java的保险业务管理系统
    Linux的shell编程易错点解析(for循环和ls命令)
    flume 通过syslog协议读取系统日志
    基于PHP+MySQL音乐网站的设计与实现
    MySQL:日志系统介绍 | 错误日志 | 查询日志 | 二进制日志:bin-log数据恢复实践 | 慢日志查询
  • 原文地址:https://blog.csdn.net/weixin_44495599/article/details/126184802