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

[Python 基础课程]继承

在 Python 的面向对象编程(OOP)中,继承(Inheritance) 是一种重要的机制,它允许一个类(称为子类派生类)从另一个类(称为父类基类超类)中继承属性和方法。

为什么需要继承

考虑我们之前定义的 Person 类,现在我们想创建 StudentTeacher 类。它们都属于“人”,所以都有姓名和年龄。

# 传统的做法,没有继承
class Person:def __init__(self, name, age):self.name = nameself.age = agedef introduce(self):print(f"大家好,我叫 {self.name},今年 {self.age} 岁。")class Student:def __init__(self, name, age, student_id):# 代码重复self.name = name# 代码重复self.age = age self.student_id = student_iddef introduce(self):# 代码重复print(f"大家好,我叫 {self.name},今年 {self.age} 岁。")print(f"我的学号是 {self.student_id}。")class Teacher:def __init__(self, name, age, subject):# 代码重复self.name = name# 代码重复self.age = age self.subject = subjectdef introduce(self):# 代码重复print(f"大家好,我叫 {self.name},今年 {self.age} 岁。")print(f"我教 {self.subject}。")

你会发现 nameage 属性以及 introduce 方法在 PersonStudentTeacher 类中重复出现了。这种代码重复会导致:

  • 维护困难: 如果你需要修改“人”的共同行为(比如 introduce 方法),你必须在所有相关的类中都修改一遍。
  • 扩展性差: 每增加一个新的“人”的角色(比如 Employee),你都要重新编写这些通用部分。

继承就是为了解决这些问题: 它允许你定义一个通用的父类,把共同的属性和方法放在父类中。然后,特定的子类可以继承这些共同部分,并添加自己独有的属性和方法,或者修改(重写)父类的行为。

继承的基本用法

在 Python 中,子类在定义时,在类名后面的括号中指定它所继承的父类。

class ChildClass(ParentClass, OtherParentClass):

示例:PersonStudentTeacher 的继承关系

class Person:species = "人类" # 类属性def __init__(self, name, age):self.name = nameself.age = ageprint(f"创建了一个 Person 对象: {self.name}")def introduce(self):print(f"大家好,我叫 {self.name},今年 {self.age} 岁,是 {self.species}。")def celebrate_birthday(self):self.age += 1print(f"{self.name} 过生日了,现在 {self.age} 岁了!")# Student 继承自 Person
class Student(Person):def __init__(self, name, age, student_id):# 调用父类 (Person) 的构造器来初始化共同属性super().__init__(name, age)# Student 独有的属性self.student_id = student_idprint(f"创建了一个 Student 对象: {self.name}, 学号: {self.student_id}")# 重写 (Override) 父类的 introduce 方法def introduce(self):# 调用父类的 introduce 方法,重用其逻辑super().introduce()print(f"我的学号是 {self.student_id}。")def study(self):# Student 独有的方法print(f"{self.name} 正在努力学习。")# Teacher 继承自 Person
class Teacher(Person):def __init__(self, name, age, subject):# 调用父类 (Person) 的构造器super().__init__(name, age)# Teacher 独有的属性self.subject = subject print(f"创建了一个 Teacher 对象: {self.name}, 教授: {self.subject}")# 重写父类的 introduce 方法def introduce(self):# 重用父类的 introduce 逻辑super().introduce()print(f"我教 {self.subject}。")def teach(self):# Teacher 独有的方法print(f"{self.name} 正在教 {self.subject}。")# --- 演示与测试 ---
print("--- 创建对象 ---")
person = Person("王五", 40)
student = Student("小明", 18, "S12345")
teacher = Teacher("李老师", 35, "数学")print("\n--- 调用方法 ---")
person.introduce()
person.celebrate_birthday()student.introduce()
student.study()
# 继承自 Person
student.celebrate_birthday()teacher.introduce()
teacher.teach()
# 继承自 Person
teacher.celebrate_birthday() 

在 Python 中,子类默认会继承父类的所有属性和方法。如果你想让父类的某个属性不被继承,可以通过使用 __ 前缀创建私有属性。

class Parent:# 这是一个私有属性,子类无法直接访问__private_property = "这是父类的私有属性"def __init__(self):# 这是一个私有实例属性self.__private_instance_property = "这是父类的私有实例属性"def get_private_property(self):# 通过方法返回私有属性print(self.__private_property)print(self.__private_instance_property)class Child(Parent):def __init__(self):# 调用父类的构造函数super().__init__()print("尝试从子类访问父类的私有属性:")try:# 尝试访问父类的私有属性,会引发 AttributeErrorprint(self.__private_instance_property)except AttributeError as e:print(f"  错误:{e}")# 创建子类实例
child_obj = Child()
# 尝试从外部访问父类的私有属性,也会引发 AttributeError
try:print(child_obj.__private_instance_property)
except AttributeError as e:print(f"  外部访问错误:{e}")print("\n通过父类方法访问:")
# 通过父类的方法可以成功访问
child_obj.get_private_property()

super() 函数

在子类中,我们经常需要调用父类的方法,特别是父类的构造器 __init__()。这时,我们使用内置的 super() 函数。

  • super().__init__(...) 调用父类的 __init__ 方法来初始化父类定义的属性。这是一种推荐的做法,确保父类的初始化逻辑得到执行。
  • super().method_name(...) 调用父类的其他方法。这在子类重写了父类方法后,仍想在子类中执行父类的原始逻辑时非常有用。

:::warning
在 Python 3 中,super() 函数不带参数就可以自动获取当前类和实例,所以直接写 super().__init__(...) 即可。在 Python 2 中,可能需要写成 super(ChildClass, self).__init__(...)

:::

方法重写

当子类中定义了一个与父类中同名的方法时,子类的方法会**覆盖(override)**父类的方法。这意味着当你通过子类的实例调用该方法时,会执行子类中定义的方法。

在上面的示例中,StudentTeacher 类都重写了 Person 类的 introduce 方法。重写时,它们还通过 super().introduce() 调用了父类的 introduce 方法,以在添加自己特有信息的同时,保留父类的通用介绍。

多重继承

Python 允许一个子类继承多个父类,这被称为多重继承

语法如下:

class ChildClass(Parent1, Parent2, ...):

当一个子类继承了多个父类,并且这些父类中有同名的方法或属性时,Python 会遵循**方法解析顺序(Method Resolution Order, MRO)**来查找方法或属性。你可以通过 ChildClass.__mro__ 属性或 help(ChildClass) 来查看 MRO。

:::warning
在 Python 中,MRO(Method Resolution Order,方法解析顺序) 是一个决定多重继承下方法或属性查找顺序的规则。它采用 C3 线性化算法 计算,确保类继承关系的一致性和可预测性。

:::

class Flying:def fly(self):print("I can fly!")class Swimming:def swim(self):print("I can swim!")# 鸭子既能飞又能游
class Duck(Flying, Swimming):def quack(self):print("Quack! Quack!")duck = Duck()
duck.fly()
duck.swim()
duck.quack()print(Duck.__mro__) # 查看方法解析顺序

:::warning
多重继承虽然强大,但也可能导致复杂的继承关系和“菱形继承问题”(diamond problem)。在使用时需要谨慎,并理解 MRO。

:::

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

相关文章:

  • [Linux] RAID存储技术
  • 【102页PPT】电子行业数字化解决方案(附下载方式)
  • 容器化部署:用Docker封装机器翻译模型与服务详解
  • 服务器可以ping通,但部署的网站打不开
  • MyBatis 的 SQL 拦截器:原理、实现与实践
  • 基于Spring Boot的快递物流仓库管理系统 商品库存管理系统
  • OpenStack Neutron中的L2 Agent与L3 Agent:新手友好指南
  • Nginx蜘蛛请求智能分流:精准识别爬虫并转发SEO渲染服务
  • RemoteCtrl-初步的网络编程框架搭建
  • Linux 多线程:线程回收策略 线程间通信(互斥锁详解)
  • Easytier异地组网与Nginx反向代理
  • 昇腾AI自学Day2-- 深度学习基础工具与数学
  • 楼宇自控系统赋能建筑全维度管理,实现环境、安全与能耗全面监管
  • 计算分组内时间列的最大差值
  • 【AI论文】NextStep-1:迈向大规模连续令牌自回归图像生成
  • Warning: Unable to create personal MATLAB work folder:E:\绯荤粺榛樿\鏂囨。\MATLAB
  • 1083. 数列极差问题
  • 【深度学习】基于ESRNet模型的图像超分辨率训练
  • pytest介绍(python测试框架)(@pytest.mark.parametrize、@pytest.fixtures)
  • ClaudeCode使用指南
  • 鲁老师深度学习笔记(1)—最大似然估计
  • Flutter Provider 模式实现:基于 InheritedWidget 的状态管理实现
  • 93、23种设计模式之抽象工厂模式
  • 【读论文】医疗AI大模型:百川开源Baichuan-M2
  • 23. CommonJS 和 ES6 Module 区别
  • 19.3 Transformers量化模型极速加载指南:4倍推理加速+75%显存节省实战
  • ArrayList的contains问题
  • 【C++学习篇】:基础
  • Markdown 生成 Gantt 甘特图
  • STM32硬件SPI配置为全双工模式下不要单独使用HAL_SPI_Transmit API及HAL_SPI_TransmitReceive改造方法