[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.pswp.cn/diannao/95826.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/95826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT之设计器组件功能(8大类55个组件)

组件名称 功能描述关键属性1. Layouts(布局组件)(1) Vertical Layout(垂直布局)将子控件按垂直方向依次排列layoutSpacing:控件之间的间距layoutMargin:布局边缘的边距layoutStretch:设置各控件…

java中list的api详细使用

在Java中,List是集合框架中最常用的接口之一,继承自Collection,代表有序、可重复的元素集合(允许null元素)。其核心实现类有ArrayList(数组实现,随机访问高效)、LinkedList&#xff…

Azure AI Search 探索总结

Azure AI Search 原名 Azure Cognitive Service,是Azure中用来给AI项目构建知识库的组件。知识库本质和数据库很像,但是内部的存储结构和检索算法不一样。比如并不是知识库的每一列都可以用来过滤、检索或group by,而是要根据实际情况配置。A…

高效解决 pip install 报错 SSLError: EOF occurred in violation of protocol

高效解决 pip install 报错 SSLError: EOF occurred in violation of protocol 标签: Python, pip, SSLError, Clash, 网络代理, 问题解决 一、问题描述 在Python开发中,pip 是我们最亲密的伙伴。然而,当你身处需要科学上网的环境&#xff0c…

CSS 核心知识点全解析:从基础到实战应用

大家好!今天这篇文章将系统总结 CSS 的核心知识点,从最基础的样式引入到复杂的选择器应用,再到盒子模型、文本处理等实战技巧,全程结合代码示例,让你轻松掌握 CSS 的精髓。一、CSS 是什么?为什么需要它&…

ClickHouse的学习与了解

什么是ClickHouse? ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。 在传统的行式数据库系统中,数据按如下顺序存储:RowWatchIDJavaEnableTitleGoodEventEventTime#0893543506621Investor Relations12016/5/18 5:19#1903295…

安卓11 12系统修改定制化_____修改系统 解锁system分区 去除data加密 自由删减系统应用

在定制化系统中。修改系统分区 解锁system。让用户可以自由删减应用。这个在定制化服务中比较常见。对于此项修改服务。需要我们了解基础的分区常识以及常用的几种基础修改步骤。 通过博文了解💝💝💝 1💝💝💝-----修改rom 解锁 system 分区有什么意义 2💝💝…

JetPack系列教程(八):PDF库——让Android应用也能优雅“翻页”

JetPack系列教程(八):PDF库——让Android应用也能优雅“翻页” 在Android开发的世界里,加载PDF文件一直是个让人又爱又恨的“小妖精”。爱它,因为PDF是文档界的“万能钥匙”;恨它,因为原生Andr…

Three.js三大组件:场景(Scene)、相机(Camera)、渲染器(Renderer)

上一篇中我们学习了第一个Three.js场景"Hello World"。这一篇就来学习three.js的核心组件。 此图来源(Three.js中文网) three.js的核心由三大组件构成:场景(Scene)、相机(Camera)和渲染器(Renderer)。下面我将详细介绍这三大件的作…

AI幻觉终结之后:GPT-5开启的“可靠性”新赛道与开发者生存指南

摘要: Sam Altman关于GPT-5将基本终结幻觉的宣告,不仅仅是一次技术升级,它标志着一个“万物皆可AI,但万事皆需验证”的混乱时代的结束。本文将从一个全新的战略视角出发,探讨当“可靠性”取代“创造性”成为AI竞赛的核…

ubuntu远程桌面很卡怎么解决?

服务端方案 完成XRDP的性能优化配置: 1. 首先检查当前的xrdp.ini文件 grep -n "tcp_send_buffer_bytes" /etc/xrdp/xrdp.ini2. 编辑xrdp.ini文件,修改TCP发送缓冲区大小 sudo sed -i s/#tcp_send_buffer_bytes32768/tcp_send_buffer_bytes4194…

[Linux] Linux系统负载监控 Linux服务管理

目录 Linux系统负载监控 系统负载介绍 查看系统负载 负载解读 top 命令 Linux服务管理 systemd 介绍 系统启动管理进程 基本概念 systemd 架构 unit 类型 查看 unit 列表信息 查看单个 unit 信息 控制系统服务 systemctl 命令 unit 配置文件 例:开发…

vector 手动实现 及遇到的各种细节问题

之前对vector的一些功能使用了一下 接下来手动实现一下vector vector的实现和string还是有不小区别的 有很多地方都有细节的问题不同于string的成员变量一个指针一个size一个capacity的成员变量 vector里面存的是三个迭代器iterator 这的迭代器其实就是模版T的指针 这样就…

OpenStack Neutron中的L2 Agent与L3 Agent:新手友好指南

引言:云网络的幕后英雄 在当今的云计算世界中,OpenStack作为开源云平台的佼佼者,为成千上万的企业提供了灵活、可扩展的基础设施服务。而在OpenStack的众多组件中,Neutron(网络服务)扮演着至关重要的角色—…

【自用】JavaSE--特殊文件Properties与XML、日志技术

特殊文件概述使用特殊文件可以存储多个有关系的数据,作为系统的配置信息属性文件类似于键值对,一一对应存储数据(比如用户名与密码)XML文件存储多个用户的多个属性更适合,适合存储更复杂的数据Properties注:这个属性文件的后缀即使…

中本聪思想与Web3的困境:从理论到现实的跨越

一、中本聪思想的核心精髓中本聪通过比特币白皮书提出的核心思想,可归纳为三大支柱:去中心化货币体系目标:摆脱中央机构控制,避免通货膨胀和政治干预(如2008年金融危机暴露的中心化风险)。实现路径&#xf…

Centos 用户管理

一.创建用户 在 root账户 或 sudo 权限下 1. 创建用户 useradd xiaoyangzi2.为该用户设置密码或修改密码 passwd xiaoyangzi3. 将用户加入wheel用户组 在 CentOS 中,属于 wheel 组的用户默认可以使用 sudo 权限。 查看所属用户组: groups xiaoyangzi将 xiaoyangzi 加…

C++枚举算法习题

1. 3的倍数枚举(基础)题目:在之间有10和50多少个数是3的倍数?列举这些数。 解析:枚举10到50之间的数,判断是否能被3整除。优化:计算第一个≥10的3的倍数(1234)&#xff0…

【SpringBoot系列-01】Spring Boot 启动原理深度解析

【SpringBoot系列-01】Spring Boot 启动原理深度解析 大家好!今天咱们来好好聊聊Spring Boot的启动原理。估计不少人跟我一样,刚开始用Spring Boot的时候觉得这玩意儿真神奇,一个main方法跑起来就啥都有了。但时间长了总会好奇:这…

windows环境下使用vscode以及相关插件搭建c/c++的编译,调试环境

windows下使用vscode搭建c/c的编译、运行、调试环境,需要注意的是生成的是xxx.exe可执行文件。另外使用的编译器是mingw,也就是windows环境下的GNU。 我参考的网址是:https://zhuanlan.zhihu.com/p/1936443912806962622 文章分为2种环境搭建…