当前位置: 首页 > news >正文

【Python语言基础】17、继承

文章目录

    • 1. 继承
      • 1.1 为什么要用继承
      • 1.2 继承的基本语法
      • 1.3 方法重写
      • 1.4 多重继承
    • 2. supper()
      • 2.1 作用
      • 2.2 基本语法
      • 2.3 注意事项
      • 2.4 super() 在多继承中的特点

1. 继承

在 Python 里,继承是一种强大的编程概念,它允许一个类(子类)去继承另一个类(父类)的属性和方法。就好比孩子会继承父母的一些特征和能力一样

1.1 为什么要用继承

继承的好处在于代码复用和构建清晰的类层次结构。

借助继承,无需在每个类里重复编写相同的代码,只要把通用的属性和方法放在父类中,子类就能直接使用。

1.2 继承的基本语法

以下是 Python 中实现继承的简单示例


# 定义一个父类
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name} 发出了声音。")

# 定义一个子类,继承自 Animal 类
class Dog(Animal):
    def bark(self):
        print(f"{self.name} 汪汪叫。")

# 创建一个 Dog 类的实例
dog = Dog("旺财")

# 调用从父类继承的方法
dog.speak()
# 调用子类自己的方法
dog.bark()

在这个例子中,Animal 是父类,Dog 是子类。

Dog 类通过 class Dog(Animal) 语句继承了 Animal 类。这意味着 Dog 类可以使用 Animal 类中定义的属性和方法,像 init 方法和 speak 方法。

同时,Dog 类还能有自己独特的方法,例如 bark 方法。

1.3 方法重写

子类可以对从父类继承的方法进行重写,也就是在子类里重新定义这个方法,让它有不同的行为。

下面是一个方法重写的示例:


class Animal:
    def speak(self):
        print("动物发出了声音。")

class Cat(Animal):
    def speak(self):
        print("猫咪喵喵叫。")

cat = Cat()
cat.speak()

在这个例子中,Cat 类重写了 Animal 类的 speak 方法,当调用 cat.speak() 时,会执行 Cat 类中定义的 speak 方法,输出 “猫咪喵喵叫。

1.4 多重继承

Python 还支持多重继承,也就是一个子类可以继承多个父类。

以下是多重继承的示例:


class A:
    def method_a(self):
        print("方法 A")

class B:
    def method_b(self):
        print("方法 B")

class C(A, B):
    pass

c = C()
c.method_a()
c.method_b()

在这个例子中,C 类继承了 A 类和 B 类,所以 C 类的实例可以调用 A 类和 B 类中定义的方法。

通过继承,你能够构建出复杂而灵活的类层次结构,让代码更加简洁、易于维护。

2. supper()

在 Python 里,super() 是一个非常实用的内置函数,主要用于在子类中调用父类的方法

2.1 作用

super() 函数能让子类在重写父类方法时,还可以调用父类的同名方法,这样就避免了代码重复,并且保证了类的层次结构和继承关系的正确性。

2.2 基本语法

在 Python 3 中,super() 函数的基本语法很简单,无需传递参数,通常的使用方式如下:

super().父类方法名(参数)
  1. 调用父类的构造方法
    在子类的构造方法中,常常需要调用父类的构造方法来初始化一些父类的属性。

以下是一个示例:

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


class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed


dog = Dog("旺财", "金毛")
print(f"狗狗的名字是 {dog.name},品种是 {dog.breed}。")

在这个例子中,Dog 类的 init 方法通过 super().init(name) 调用了父类 Animal 的构造方法,完成了 name 属性的初始化。

  1. 调用父类的其它方法
    当子类重写了父类的某个方法,但还需要使用父类该方法的功能时,可以用 super() 来调用。

示例如下:

class Animal:
    def speak(self):
        print("动物发出了声音。")


class Cat(Animal):
    def speak(self):
        super().speak()
        print("猫咪喵喵叫。")


cat = Cat()
cat.speak()

在这个例子中,Cat 类重写了 speak 方法,通过 super().speak() 调用了父类 Animal 的 speak 方法,然后再添加了自己独特的输出。

2.3 注意事项

  • super() 函数返回的是一个代理对象,它会按照方法解析顺序(MRO)来查找并调用父类的方法。可以使用 类名.mro 查看具体的 MRO 顺序。
  • 在多继承的情况下,super() 的调用逻辑会更复杂,要确保理解 MRO 顺序,避免出现意外的结果。

通过使用 super() 函数,可以更方便地管理类的继承关系,提高代码的复用性和可维护性。

2.4 super() 在多继承中的特点

在多继承场景下,super() 函数有着独特的特点和行为,下面从调用顺序、方法解析顺序(MRO)、参数传递和实际应用示例等方面详细介绍:

  1. 调用顺序与方法解析顺序(MRO)
  • MRO 规则:Python 使用 C3 线性化算法来确定类的方法解析顺序(MRO)。MRO 定义了在调用 super() 时,Python 查找父类方法的顺序。可以通过 类名.mro 查看具体的 MRO 顺序。
  • 特点:super() 在多继承中会按照 MRO 顺序依次调用父类的方法,而不是只调用直接父类的方法。这意味着它会沿着 MRO 链向上查找,直到找到所需的方法。
  1. 参数传递

在多继承里,super() 函数调用父类方法时,参数会按照 MRO 顺序依次传递。
当子类调用 super() 并传递参数时,这些参数会被传递给 MRO 链中的下一个类的相应方法。

  1. 实际应用示例
class A:
    def __init__(self):
        print("A 的初始化方法")


class B(A):
    def __init__(self):
        print("B 的初始化方法")
        super().__init__()


class C(A):
    def __init__(self):
        print("C 的初始化方法")
        super().__init__()


class D(B, C):
    def __init__(self):
        print("D 的初始化方法")
        super().__init__()


d = D()
print(D.__mro__)

# 结果:
D 的初始化方法
B 的初始化方法
C 的初始化方法
A 的初始化方法
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

***Repl Closed***

在上述代码中:

  • 类 D 继承自 B 和 C,而 B 和 C 又都继承自 A。
  • 创建 D 类的实例 d 时,调用 D 的 init 方法。在 D 的 init 方法中使用 super().init() 会按照 MRO 顺序调用父类的 init 方法。
  • 输出结果显示,调用顺序为 D -> B -> C -> A,这正是 D 类的 MRO 顺序。
  1. 避免重复调用

super() 能避免在多继承中对同一个父类方法的重复调用。由于它按照 MRO 顺序依次调用,每个父类方法只会被调用一次,保证了代码的正确性和效率。

  1. 注意事项
  • 要确保在多继承中每个父类的方法都正确使用 super() 调用其父类的相应方法,否则可能会破坏 MRO 顺序,导致部分父类方法未被调用。
  • 在多继承中使用 super() 时,需要对 MRO 有清晰的理解,以避免出现意外的结果。

总之,super() 在多继承中的行为由 MRO 决定,它能确保父类方法按照正确的顺序被调用,同时避免重复调用,提高代码的可维护性和复用性。

http://www.dtcms.com/a/123018.html

相关文章:

  • 深入理解 Spring 的 MethodParameter 类
  • 测试的分类
  • OpenCV 图形API(25)图像滤波-----均值滤波(模糊处理)函数blur()
  • 写一个简单的demo来理解数据库外键
  • Java中的参数是值传递还是引用传递?
  • webpack配置导致浏览器自动刷新
  • Pytest+Allure+Excel接口自动化测试框架实战
  • 【Kafka基础】监控与维护:分区健康检查,确保数据高可用
  • 【C++算法】53.链表_重排链表
  • 数据可视化 —— 柱形图应用(大全)
  • 《Uniapp-Vue 3-TS 实战开发》构建HTTP请求拦截器
  • Windows 2016 如何关闭自动更新
  • HLSL Complex Shapes With For Loops
  • Linux启动端口,Windows 看是否通
  • 使用 Vue + PDF.js 构建在线 PDF 阅读器(支持目录与缩放)
  • Petalinux最简开发
  • (2)网络学习之堡垒机
  • 如何避免Python爬虫重复抓取相同页面?
  • 【数据结构】树状数组
  • RTT中断管理学习
  • 苹果电脑MAC系统安装
  • 【MySQL篇】mysqlpump和mysqldump参数区别总汇
  • 【C++游戏引擎开发】第11篇:GLFW、GLAD环境搭建与第一个三角形渲染
  • 09-Spring 与线程安全:IOC 与多线程下的坑与解法
  • 解锁Midjourney创作潜能:超详细提示词(Prompts)分类指南
  • 【42期获取股票数据API接口】如何用Python、Java等五种主流语言实例演示获取股票行情api接口之沪深指数最新分时BOLL数据及接口API说明文档
  • 三、使用Keil5新建STM32工程
  • 【学Rust写CAD】29 Alpha256结构体(alpha256.rs)
  • torch.meshgrid()
  • 【OCR】总结目前流行的主要的OCR工具