Python 类和对象:详细讲解中篇

文章目录

  • Python 类和对象:详细讲解
    • 前言
    • 9. 方法重写(Method Overriding)
      • 9.1 为什么需要方法重写?
      • 9.2 方法重写的基本示例
      • 9.3 代码详解
    • 10. 多继承(Multiple Inheritance)
      • 10.1 多继承的概念
      • 10.2 多继承的示例
      • 10.3 代码详解
      • 10.4 方法解析顺序(MRO)
    • 11. 类的组合(Composition)
      • 11.1 什么是类的组合?
      • 11.2 类的组合的示例
        • 11.3 代码详解
        • 11.4 组合与继承的对比
      • 12. 总结3
    • 13.方法解析顺序(MRO)
      • 13.1 MRO 的基本概念
      • 13.2 查看 MRO
      • 13.3 复杂继承结构中的 MRO
    • 14. 抽象类和接口
      • 14.1 什么是抽象类?
      • 14.2 Python 中的抽象类
      • 14.3 抽象类的用途

Python 类和对象:详细讲解

前言

接上篇:

在编程中,对象是面向对象编程(OOP)的核心概念。Python 是一门支持面向对象编程的语言,这意味着你可以使用类和对象来组织代码,使其更加模块化、可维护和可扩展。


9. 方法重写(Method Overriding)

方法重写是在子类中定义与父类中同名的方法,以覆盖或扩展父类的行为。通过方法重写,子类可以改变或定制从父类继承的方法的功能。

9.1 为什么需要方法重写?

在继承中,子类会继承父类的所有方法和属性。然而,有时你可能希望子类的某些方法与父类的方法表现不同。这时,你就可以在子类中重写这些方法。

9.2 方法重写的基本示例

我们来定义一个基本的 Car 类,然后在子类 ElectricCar 中重写它的方法。

class Car:def __init__(self, brand, color):self.brand = brandself.color = colorself.speed = 0def start(self):self.speed = 10print(f"The {self.color} {self.brand} car is starting at {self.speed} km/h.")def stop(self):self.speed = 0print(f"The {self.color} {self.brand} car is stopping.")# 定义一个 ElectricCar 类,继承自 Car 类
class ElectricCar(Car):def __init__(self, brand, color, battery_capacity):super().__init__(brand, color)  # 调用父类的构造函数初始化 brand 和 colorself.battery_capacity = battery_capacitydef start(self):# 重写 start 方法,让电动汽车以不同的方式启动self.speed = 20  # 电动汽车启动时速度更快print(f"The {self.color} {self.brand} electric car is silently starting at {self.speed} km/h with {self.battery_capacity} kWh capacity.")def charge(self):print(f"The {self.color} {self.brand} electric car is charging with {self.battery_capacity} kWh capacity.")# 创建 ElectricCar 对象并使用它
electric_car = ElectricCar("Tesla", "White", 85)
electric_car.start()  # 输出: The White Tesla electric car is silently starting at 20 km/h with 85 kWh capacity.
electric_car.stop()   # 输出: The White Tesla car is stopping.
electric_car.charge()  # 输出: The White Tesla electric car is charging with 85 kWh capacity.

9.3 代码详解

  • 父类 Car 的方法Car 类定义了 startstop 方法。start 方法设置初始速度为 10 km/h,stop 方法将速度设为 0。
  • 子类 ElectricCar 的方法重写:
    • ElectricCar 继承了 Car 的所有属性和方法。
    • ElectricCar 重写了 start 方法,使其启动速度为 20 km/h,并增加了电池容量的输出。
    • super().__init__(brand, color) 调用了父类的构造函数,以确保 brandcolor 属性被正确初始化。

10. 多继承(Multiple Inheritance)

多继承是指一个类可以同时继承多个父类的特性。Python 支持多继承,但使用时需要注意可能的复杂性,尤其是在多个父类中有相同方法的情况下。

10.1 多继承的概念

多继承允许一个子类同时从多个父类中继承方法和属性。这种特性非常强大,但也可能带来复杂的依赖关系。

10.2 多继承的示例

创建两个父类 VehicleElectric,然后定义一个子类 ElectricCar,它同时继承自这两个父类。

class Vehicle:def __init__(self, brand):self.brand = branddef start(self):print(f"The {self.brand} vehicle is starting.")class Electric:def __init__(self, battery_capacity):self.battery_capacity = battery_capacitydef charge(self):print(f"Charging with {self.battery_capacity} kWh battery capacity.")# ElectricCar 继承了 Vehicle 和 Electric
class ElectricCar(Vehicle, Electric):def __init__(self, brand, color, battery_capacity):Vehicle.__init__(self, brand)  # 初始化 Vehicle 类的属性Electric.__init__(self, battery_capacity)  # 初始化 Electric 类的属性self.color = colordef start(self):print(f"The {self.color} {self.brand} electric car is silently starting with {self.battery_capacity} kWh battery.")# 使用 ElectricCar 类
electric_car = ElectricCar("Tesla", "White", 85)
electric_car.start()   # 输出: The White Tesla electric car is silently starting with 85 kWh battery.
electric_car.charge()  # 输出: Charging with 85 kWh battery capacity.

10.3 代码详解

  • VehicleElectric 父类:这两个类分别提供 brandbattery_capacity 属性,并各自定义了 startcharge 方法。
  • ElectricCar 的多继承:
    • ElectricCar 同时继承了 VehicleElectric 的属性和方法。
    • 通过在 __init__ 方法中分别调用 Vehicle.__init__(self, brand)Electric.__init__(self, battery_capacity) 来初始化父类的属性。
    • ElectricCar 中的 start 方法重写了 Vehicle 类的 start 方法,以自定义启动行为。

10.4 方法解析顺序(MRO)

当使用多继承时,Python 会根据方法解析顺序(MRO)来决定调用哪个父类的方法。MRO 是 Python 确定方法调用顺序的规则。

  • 查看 MRO

    • 你可以通过 ClassName.mro() 方法查看一个类的 MRO。

    例如:

    print(ElectricCar.mro())
    

    这将输出:

    [<class '__main__.ElectricCar'>, <class '__main__.Vehicle'>, <class '__main__.Electric'>, <class 'object'>]
    
  • MRO 解析顺序:Python 会从左到右、从上到下地查找方法。在本例中,ElectricCar 先查找自身,然后是 Vehicle,接着是 Electric,最后是 Python 所有类的基类 object


11. 类的组合(Composition)

类的组合是指一个类可以包含其他类的实例作为属性,从而创建更复杂的对象。与继承相比,组合更灵活,因为它不涉及继承链的复杂性。

11.1 什么是类的组合?

类的组合通过在一个类中包含另一个类的实例,来实现功能模块化。这种方法使得类的职责更加明确,也让代码更加易于维护。

11.2 类的组合的示例

让我们定义一个 Battery 类,并将其组合到 ElectricCar 中。

class Battery:def __init__(self, capacity):self.capacity = capacitydef charge(self):print(f"Charging the battery with {self.capacity} kWh capacity.")class ElectricCar:def __init__(self, brand, color, battery_capacity):self.brand = brandself.color = colorself.battery = Battery(battery_capacity)  # 组合 Battery 类def start(self):print(f"The {self.color} {self.brand} electric car is starting.")def charge(self):self.battery.charge()  # 调用 Battery 类的 charge 方法# 使用 ElectricCar 类
electric_car = ElectricCar("Tesla", "White", 85)
electric_car.start()  # 输出: The White Tesla electric car is starting.
electric_car.charge()  # 输出: Charging the battery with 85 kWh capacity.
11.3 代码详解
  • Battery 类Battery 类代表电动汽车的电池。它有一个 charge 方法来模拟充电。
  • ElectricCar 的组合:
    • ElectricCar 类拥有一个 Battery 类的实例,作为其 battery 属性。
    • 当调用 electric_car.charge() 时,实际是调用 Battery 类的 charge 方法。
11.4 组合与继承的对比
  • 继承:用于创建一个“是一个”关系的类结构,例如 ElectricCar 是一个 Car
  • 组合:用于创建一个“有一个”关系的类结构,例如 ElectricCar 有一个 Battery

组合通常比继承更灵活,因为你可以在不改变类继承层次的情况下,动态地更改组合类的行为。


12. 总结3

在本次学习中,你已经掌握了以下关键概念:

  • 方法重写:通过在子类中定义与父类同名的方法,你可以重写父类的方法,从而定制子类的行为。重写方法时,子类的方法会覆盖父类的同名方法,这是实现多态性的重要方式。
  • 多继承:Python 支持一个类同时继承多个父类的属性和方法。多继承虽然强大,但使用时需要注意方法解析顺序(MRO)和潜在的复杂性。通过多继承,你可以复用多个类的功能,从而创建功能更加丰富的子类。
  • 类的组合:通过在一个类中包含其他类的实例,你可以创建复杂的对象结构。这种方法比多继承更加灵活且易于维护,因为它不涉及复杂的继承关系。组合强调对象之间的协作,而不是继承层次中的耦合。

13.方法解析顺序(MRO)

在多继承中,方法解析顺序(MRO)是 Python 用来确定类层次结构中的方法调用顺序的机制。理解 MRO 对于有效使用多继承和调试复杂的类层次结构非常重要。

13.1 MRO 的基本概念

MRO 决定了当你调用一个方法时,Python 如何查找该方法的定义。MRO 是通过一种称为 C3 线性化的算法来计算的,该算法确保了类层次结构中的一致性和方法解析的确定性。

13.2 查看 MRO

你可以使用类的 mro() 方法或 __mro__ 属性来查看一个类的 MRO。

例如:

class A:passclass B(A):passclass C(A):passclass D(B, C):passprint(D.mro())

输出将显示 D 类的 MRO:

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

13.3 复杂继承结构中的 MRO

当类层次结构变得复杂时,MRO 可以帮助你理解方法调用的顺序。例如,如果 D 类继承了 BC,而 BC 又都继承自 A,MRO 可以告诉你调用 D 的方法时,Python 是如何在 BCA 之间选择方法的。

通过了解 MRO,你可以避免潜在的方法冲突,并确保你的代码在多继承情况下能够按照预期工作。


14. 抽象类和接口

在面向对象编程中,抽象类和接口用于定义类的框架和通用行为,确保子类实现这些行为。

14.1 什么是抽象类?

抽象类是一种不能被实例化的类,它通常用于定义子类必须实现的方法。抽象类提供了一个模板,让你可以确保所有子类都具有某些共同的行为。

14.2 Python 中的抽象类

在 Python 中,你可以使用 abc 模块中的 ABCabstractmethod 来定义抽象类和抽象方法。

例如:

from abc import ABC, abstractmethodclass Animal(ABC):@abstractmethoddef sound(self):passclass Dog(Animal):def sound(self):return "Woof!"class Cat(Animal):def sound(self):return "Meow!"

在这个例子中,Animal 是一个抽象类,它定义了一个抽象方法 sound。任何继承 Animal 的子类都必须实现 sound 方法,否则会引发错误。

14.3 抽象类的用途

  • 统一接口:抽象类强制子类实现某些方法,从而确保所有子类有统一的接口。
  • 代码复用:抽象类可以包含具体的方法实现,这些方法可以被子类继承和复用。
  • 增强代码的可维护性:通过抽象类,你可以更容易地理解和维护子类之间的关系和行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67966.shtml

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

相关文章

C语言文件操作:标准库与系统调用实践

目录 1、C语言标准库文件操作 1.1.题目要求&#xff1a; 1.2.函数讲解&#xff1a; fopen 函数原型 参数 常用的打开模式 返回值 fwrite函数 函数原型 参数 返回值 注意事项 fseek函数 函数原型 参数 返回值 fread函数 函数原型 参数 返回值 fclose 函数…

一款专业通用开源的MES生产执行管理系统

系统简介 MES系统是一款B/S结构、开源、免费的生产执行管理系统。 此系统基于本人多年离散智造行业的业务经验及J2EE项目经验开发。 主要目的是为国内离散制造业的中小企业提供一个专业化、通用性、低成本的MES系统解决方案。 系统将提供“售前”、“实施”、“用户培训”、…

SpringBoot集成Flink-CDC,实现对数据库数据的监听

一、什么是 CDC &#xff1f; CDC 是Change Data Capture&#xff08;变更数据获取&#xff09;的简称。 核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数据表的插入、 更新以及删除等&#xff09;&#xff0c;将这些变更按发生的顺序完整记录下来&…

Three城市引擎地图插件Geo-3d

一、简介 基于Three开发&#xff0c;为Three 3D场景提供GIS能力和城市底座渲染能力。支持Web墨卡托、WGS84、GCJ02等坐标系&#xff0c;支持坐标转换&#xff0c;支持影像、地形、geojson建筑、道路&#xff0c;植被等渲染。支持自定义主题。 二、效果 三、代码 //插件初始化…

应用层协议 HTTP 讲解实战:从0实现HTTP 服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; HTTP 协议 &#x1f98b; 认识 URL&#x1f98b; urlencode 和 urldecode 二&#xff1a;&#x1f525; HTTP 协议请求与响应格式 &#x1f98b; HTTP 请求…

鸿蒙仓颉环境配置(仓颉SDK下载,仓颉VsCode开发环境配置,仓颉DevEco开发环境配置)

目录 ​1&#xff09;仓颉的SDK下载 1--进入仓颉的官网 2--点击图片中的下载按钮 3--在新跳转的页面点击即刻下载 4--下载 5--找到你们自己下载好的地方 6--解压软件 2&#xff09;仓颉编程环境配置 1--找到自己的根目录 2--进入命令行窗口 3--输入 envsetup.bat 4--验证是否安…

CPU 缓存基础知识

并发编程首先需要简单了解下现代CPU相关知识。通过一些简单的图&#xff0c;简单的代码&#xff0c;来认识CPU以及一些常见的问题。 目录 CPU存储与缓存的引入常见的三级缓存结构缓存一致性协议MESI协议缓存行 cache line 通过代码实例认识缓存行的重要性 CPU指令的乱序执行通过…

计算机网络 (56)交互式音频/视频

一、定义与特点 定义&#xff1a;交互式音频/视频是指用户使用互联网和其他人进行实时交互式通信的技术&#xff0c;包括语音、视频图像等多媒体实时通信。 特点&#xff1a; 实时性&#xff1a;音频和视频数据是实时传输和播放的&#xff0c;用户之间可以进行即时的交流。交互…

pdf与ofd的区别详细对比

PDF&#xff08;Portable Document Format&#xff09;和OFD&#xff08;Open Fixed-layout Document&#xff09;是两种常见的电子文档格式&#xff0c;它们在设计理念、技术实现、应用场景等方面存在显著差异。以下是对这两种格式的详细对比分析&#xff0c;涵盖其历史背景、…

【Linux系统】Linux下的图形库 ncurses(简单认识)

基本介绍 在 Linux 环境下&#xff0c;ncurses 是一个非常重要的库&#xff0c;用于编写可以在终端&#xff08;TTY&#xff09;或模拟终端窗口中运行的 字符界面程序。它提供了一套函数&#xff0c;使得开发者可以轻松地操作文本终端的显示&#xff0c;比如移动光标、创建窗口…

基于C#实现多线程启动停止暂停继续

大部分初学者在学习C#上位机编程时&#xff0c;多线程是一个很难逾越的鸿沟&#xff0c;不合理地使用多线程&#xff0c;会导致经常出现各种奇怪的问题&#xff0c;这也是很多初学者不敢使用多线程的原因。但是在实际开发中&#xff0c;多线程是一个不可避免的技术栈&#xff0…

ESP8266 MQTT服务器+阿里云

MQTT私有平台搭建&#xff08;EMQX 阿里云&#xff09; 阿里云服务器 EMQX 搭建私有MQTT平台 1、搜索EMQX开源版本 2、查看各版本EMQX支持的UBUNTU版本 3、查看服务器Ubuntu版本 4、使用APT安装模式 5、按照官网指示安装并启动 6、下载安装MQTTX测试工具 7、设置云服务…

OpenCV相机标定与3D重建(63)校正图像的畸变函数undistort()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 转换图像以补偿镜头畸变。 该函数通过变换图像来补偿径向和切向镜头畸变。 此函数仅仅是 initUndistortRectifyMap&#xff08;使用单位矩阵 R…

Redis使用基础

1 redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务 ! 是完全开源的&#xff0c;遵守 BSD 协议&#xff0c;是一个高性能的 key-value 数据库。 使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并…

vector详解(C++)

参考&#xff1a;C vector链接&#xff1a;http://www.cplusplus.com/reference/vector/vector/ 1.vector vector 是 C STL 中一种顺序容器&#xff08;sequence container&#xff09;&#xff0c;其底层实现基于动态数组。与普通数组不同的是&#xff0c;vector 可以根据需…

Spring Boot 事件驱动:构建灵活可扩展的应用

在 Spring Boot 应用中&#xff0c;事件发布和监听机制是一种强大的工具&#xff0c;它允许不同的组件之间以松耦合的方式进行通信。这种机制不仅可以提高代码的可维护性和可扩展性&#xff0c;还能帮助我们构建更加灵活、响应式的应用。本文将深入探讨 Spring Boot 的事件发布…

PostgreSQL主从复制配置

本文主要介绍基于pg_basebackup实现主从复制&#xff08;异步流复制&#xff09; MASTER节点安装的方法可以看这篇文章 PostgreSQL YUM安装_yum install postgresql-CSDN博客 关于基本的配置就不作过多的介绍了&#xff0c;直接开始 MASTER节点 首先在master节点创建一个用于…

2025 OWASP十大智能合约漏洞

随着去中心化金融&#xff08;DeFi&#xff09;和区块链技术的不断发展&#xff0c;智能合约安全的重要性愈发凸显。在此背景下&#xff0c;开放网络应用安全项目&#xff08;OWASP&#xff09;发布了备受期待的《2025年智能合约十大漏洞》报告。 这份最新报告反映了不断演变的…

linux下使用脚本实现对进程的内存占用自动化监测

linux系统中常用cat /proc/{pid}/status和pmap -x {pid}来监测某个进程的内存资源占用情况。 其中注意各参数的含义如下&#xff1a; VmSize&#xff1a;表示进程当前虚拟内存大小 VmPeak&#xff1a;表示进程所占用最大虚拟内存大小 VmRSS&#xff1a;表示进程当前占用物理内…

双足机器人开源项目

双足机器人&#xff08;也称为人形机器人或仿人机器人&#xff09;是一个复杂的领域&#xff0c;涉及机械设计、电子工程、控制理论、计算机视觉等多个学科。对于想要探索或开发双足机器人的开发者来说&#xff0c;有许多开源项目可以提供帮助。这些项目通常包括硬件设计文件、…