08. 面向对象编程(二)

目录

1、前言

2、多重继承

2.1、潜在的问题

3、@Property

4、@staticmethod

5、运算符重载

5.1、加法运算符 + 的重载

5.2、字符串表示运算符 str() 的重载

5.3、索引运算符 [] 的重载

6、小结


1、前言

上一篇文章中,我们介绍了面向对象编程的类和实例,以及三大基本特性。今天我们继续来了解面向对象编程的其他知识。

2、多重继承

多重继承是面向对象编程中的一个概念,它允许一个类同时继承自多个父类。这使得子类可以继承多个父类的属性和方法。在Python中,多重继承是支持的,但需要小心使用,因为它可能引起一些设计上的复杂性和潜在的问题。

多重继承的场景:举个例子,我们现在可能会拥有多种角色,比如程序员(Programmer)以及老父亲(Father)。那么Python中我们可能定义两个类:

# 老父亲类
class Father:pass# 程序员类
class Programmer:pass

同时,两个不同的类拥有一个相同的方法(eat)和各自不同的方法:老父亲拥有泡奶粉的方法,程序员需要加班改bug的方法。代码示例:

# 老父亲类
class Father:# 老父亲需要泡奶粉的动作def soak_milk(self):print("我是一位老父亲,加班到家后要给娃泡奶粉")# 老父亲也要吃饭def eat(self):print("老父亲要吃饭,吃面条")# 程序员类
class Programmer:# 程序员要加班改bugdef fix_bug(self):print("我是一位程序猿,需要加班改bug")# 程序员也要吃饭def eat(self):print("程序员要吃饭,吃快餐")

最后,我同时拥有这两个角色,那么创建一个我的类,继承了Father和Programmer,之后创建出来的实例就同时拥有了老父亲泡奶粉的能力,以及程序员加班改bug的能力。完整示例代码:

# 创建一个我的类,多重继承Father和Programmer
class Me(Father, Programmer):pass# 创建一个我的实例
me = Me()
# 我要吃饭
me.eat()
# 老父亲泡奶粉
me.soak_milk()
# 程序员改bug
me.fix_bug()

执行结果:

从上述代码中可以看出,多重继承的语法为class 类名(父类1, 父类2...)。如果继承的多个父类中有相同的方法,那么最先执行最左继承的父类。什么?你问我怎么知道的?我猜的!!!来看我猜的对不对,Python提供了一个特殊的方法__mro__来查看类的方法解析顺序。

在多重继承中,Python 使用 C3 线性化算法来确定方法的调用顺序,这被称为方法解析顺序(Method Resolution Order,简称MRO)。MRO 定义了从多个父类中继承方法时的顺序,它是基于 C3 算法生成的线性列表。

查看结果:

先解析Me类,之后是Father,再Programmer。诚不欺客,没骗人吧!

2.1、潜在的问题

尽管多重继承提供了一定的灵活性,但也容易导致一些设计上的复杂性和潜在的问题,例如:

  • 菱形继承问题: 当一个子类继承自两个有共同父类的类时,可能会出现方法冲突的问题。Python 的 MRO 算法通常能够解决这个问题,但在复杂的继承结构中,需要小心设计以避免混淆。
  • 代码可读性:多重继承可能导致代码可读性降低,因为需要追踪多个父类的方法和属性。
  • 耦合性: 过度使用多重继承可能导致类之间的高度耦合,降低了代码的灵活性和可维护性。

3、@Property

@property 是 Python 中用于将方法转换为只读属性的装饰器。通过使用 @property 装饰器,你可以定义一个方法,使之在调用时表现得像一个属性一样。这有助于隐藏类的内部实现细节,提高代码的可读性。正如上一篇中提到受保护成员的访问控制时,除了使用公开方法访问外,还可以此装饰器进行访问。

class Girl:def __init__(self, name, age):self.name = nameself.age = ageself._weight = 90   # 女孩子的体重当然是秘密了def get_weight(self):return self._weightgirl = Girl("小花", 20)
# 访问方式1
print(f"{girl.name}今年{girl.age}岁,体重{girl._weight}公斤")
# 访问方式2
print(f"{girl.name}今年{girl.age}岁,体重{girl.get_weight()}公斤")

上面代码是前面介绍到的访问方式,除了这两个以外,还可以使用@Property。代码改造一下:

class Girl:def __init__(self, name, age):self.name = nameself.age = ageself._weight = 90  # 女孩子的体重当然是秘密了def get_weight(self):return self._weight# @Property注解装饰的,是被视为只读的属性@propertydef weight(self):return self._weightgirl = Girl("小花", 20)
print(f"{girl.name}今年{girl.age}岁,体重{girl.weight}公斤")

也是可以访问的,当我们调用girl.weight时,实际上并不是直接访问属性,而是调用get_weight()方法。使用@Property只是简化了get_weight()的调用方式。

但是值得注意的是@Property注释的属性会被视为只读属性,如果此时你试图修改它,那么Python解释器会给你抛出异常,告诉你他没有setter方法。

当然,如果我们已添加了@Property后,还可以使用“@属性名称.setter"方式来定义属性的setter方法。

class Girl:def __init__(self, name, age):self.name = nameself.age = ageself._weight = 90def get_weight(self):return self._weight# @Property注解装饰的,是被视为只读的属性@propertydef weight(self):return self._weight# 添加   @属性名称.setter   表示给该属性添加了setter方法,该setter方法允许你修改该变量的值@weight.setterdef weight(self, val):self._weight = valgirl = Girl("小花", 20)
print(f"{girl.name}今年{girl.age}岁,体重{girl.weight}公斤")
girl.weight = 200
print(f"{girl.name}今年{girl.age}岁,体重{girl.weight}公斤")

这时候,我们运行程序就不会报错了:

4、@staticmethod

@staticmethod 是 Python 中用于定义静态方法的装饰器。静态方法是类中的方法,与类的实例无关,因此它不会访问或修改实例的状态。静态方法通常用于执行与类相关的操作,而不需要访问实例的属性。

class MyClass:@staticmethoddef static_method_with_decorator():return "I am a static method with decorator"def static_method_without_decorator():return "I am a static method without decorator"# 通过类名调用带有装饰器的静态方法
result1 = MyClass.static_method_with_decorator()
print(result1)  # 输出: I am a static method with decorator# 通过类名调用没有装饰器的静态方法(不推荐)
result2 = MyClass.static_method_without_decorator()
print(result2)  # 输出: I am a static method without decorator

运行结果:

但是你会发现,其实加不加@staticmethod都允许用类名来访问静态方法,那么既然如此为什么要加上这个注解呢?其实,在 Python 中,加不加 @staticmethod 装饰器影响的是对方法的理解和类的设计风格。从功能上来说,不加 @staticmethod 也可以正常工作,因为 Python 允许通过类名直接调用类的方法。

然而,使用 @staticmethod 装饰器有一些优点:

  • 清晰性:@staticmethod 装饰器明确地表明某个方法是静态方法,提高了代码的可读性。读者可以立即看到这个方法是与类相关但与实例无关的。
  • 一致性:在类中使用 @staticmethod 保持了方法定义的一致性,使得在查看类的方法时更容易识别哪些方法是静态的。
  • IDE支持: 使用 @staticmethod 可以让一些集成开发环境(IDE)更好地支持代码提示和文档生成。

5、运算符重载

运算符重载是指在类中定义特殊方法,使得该类的实例对象可以支持一些内建运算符(如+、-、*等)的操作。通过重载运算符,我们可以定义自定义的行为,使得类对象可以与运算符一样被操作。

在Python中,运算符重载是通过特殊方法来实现的,这些方法以双下划线开头和结尾,例如 __add__、__sub__、__mul__等。以下是一些常用的运算符重载方法。

5.1、加法运算符 + 的重载

class Point:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):if isinstance(other, Point):return Point(self.x + other.x, self.y + other.y)else:raise TypeError("Unsupported operand type")p1 = Point(1, 2)
p2 = Point(3, 4)
result = p1 + p2
print(result.x, result.y)  # 输出: 4 6

5.2、字符串表示运算符 str() 的重载

class Point:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return f"Point({self.x}, {self.y})"p = Point(1, 2)
print(str(p))  # 输出: Point(1, 2)

5.3、索引运算符 [] 的重载

class Vector:def __init__(self, values):self.values = valuesdef __getitem__(self, index):return self.values[index]v = Vector([1, 2, 3, 4, 5])
print(v[2])  # 输出: 3

运算符重载为类提供了更自然和直观的使用方式,使得类的实例对象可以像内建类型一样参与各种操作。然而,需要小心不要滥用运算符重载,以避免使代码变得难以理解和维护。

6、小结

面向对象的内容远不及如此,这里只是简单介绍了最最常用的部分内容,帮助学习和入门。更多的面向对象使用还是需要结合实际项目,才会更加深入和彻底的学习掌握。今天就到这吧,一起学习,一起加油!

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

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

相关文章

v35-36.problems

1.size of()运算符 根据c语言标准规范,Size of() 里面的操作数如果不是可变长度数组类型 ,那么此操作数就不会被执行 !

x-cmd pkg | skate - 个人键值对存储工具

目录 简介用户首次快速实验指南功能特点竞品和相关作品进一步探索 简介 skate 是个人键值对存储工具,具备数据加密、云端数据备份以及多设备同步等功能。 它由 Charm 团队开发,借用 Charm Cloud 向用户提供一种快捷的方式来保存和检索各种数据&#xf…

零基础学习【Linux】这一篇就够了

Linux学习目录 1. Linux简介1-1. Linux系统版本 2. Linux安装2-1. 安装方式2-2. Vmware安装2-3. Linux安装2-4. Vmware克隆2-5. Vmware快照2-6. 连接工具安装 3. Linux常用命令4. Linux软件安装5. 项目部署 1. Linux简介 1-1. Linux系统版本 Linux系统分为内核版和发行版 内核…

「斗破年番」大紫研爆虐六星斗皇,佛怒火连回归,异火焚烧分身

Hello,小伙伴们,我是拾荒君。 国漫《斗破苍穹年番》第80期超前爆料,据透露韩枫以海心焰这一异火贡献给了慕骨老人,换取了一具斗宗躯体。通过灵魂融入,他成功达到了斗宗四星阶段。而与小医仙对决的莫天行,尽管两人实力…

Java设计模式详解-更新中

收藏和关注的同时,请也关注 公众号 “IT技术馆” 各位大家好,从今天开始,作者开始整理 《JAVA软件设计模式(GOF)》 专栏。请各位多多关注! 该专栏是根据作者的技术经验和设计模式的了解,进行详…

从零开始c++精讲:第三篇——内存管理

文章目录 一、C/C内存分布二、C语言中动态内存管理方式:malloc/calloc/realloc/free三、C中动态内存管理四、operator new与operator delete函数4.1 operator new与operator delete函数(重点) 五、new和delete的实现原理5.1内置类型5.2 自定义类型 六、定…

代码随想录二刷 | 回溯 | 组合优化

代码随想录二刷 &#xff5c; 回溯 &#xff5c; 组合优化 剪枝优化 剪枝优化 在遍历的过程中有如下代码&#xff1a; for (int i startIndex; i < n; i) {path.pop_back();backtracking(n, k, i 1);path.pop_back(); }n 4&#xff0c;k 4的话&#xff0c;那么第一层f…

打折:阿里云国外服务器价格购买优惠活动

阿里云国外服务器优惠活动「全球云服务器精选特惠」&#xff0c;国外服务器租用价格24元一个月起&#xff0c;免备案适合搭建网站&#xff0c;部署独立站等业务场景&#xff0c;阿里云服务器网aliyunfuwuqi.com分享阿里云国外服务器优惠活动&#xff1a; 全球云服务器精选特惠…

idea 折叠某段代码 这段特定某段代码

如何折叠IntelliJ IDEA代码片段_w3cschool ctrlALTT

圆的参数方程是如何推导的?

圆的参数方程是如何推导的? 1. 圆的三种参数表示2. 三角函数万能公式3. 回到圆的参数方程1. 圆的三种参数表示 已知圆的第一种参数方程为: x 2 + y 2 = r x^2+y^2=r x2+y2=r   圆的图像如下: 通过上图,不难理解,圆的参数方程还可以用三角函数表示,也就是第二种参数表…

计算机毕业设计 | SpringBoot学生成绩管理系统(附源码)

1&#xff0c; 概述 1.1 课题背景 开发一个学生成绩管理系统&#xff0c;采用计算机对学生成绩进行处理&#xff0c;进一步提高了办学效益和现代化水平。为广大教师和学生提高工作效率&#xff0c;实现学生成绩信息管理工作流程的系统化、规范化和自动化。现在我国中学的学生…

基于STM32CubeMX创建FreeRTOS—以STM32F429为例

目录 1. 实验任务 2. 使用STM32CubeMX创建基础工程 2.1 打开STM32CubeMX 2.2 创建新项目 2.3 时钟设置 2.5 修改时钟基准&#xff0c;打开串行调试 2.6 配置串口 2.7 配置状态指示灯 2.8 FreeRTOS 2.9 配置工程输出项 3. 代码编辑 3.1 printf重映射 3.1.1 使用ARM…

【JavaEE】网络初识 (IP地址, 端口号, 协议, 封装和分用)

文章目录 前言网络通信基础一.IP地址概念格式特殊IP 二.端口号概念注意事项 三.协议概念知名协议的默认端口五元组协议分层OSI七层模型TCP/IP五层模型 四.封装和分用 前言 本章来介绍一下网络中的一些基本概念, 例如 : IP地址, 端口号, 协议, 协议分层, 封装, 分用等等. 网络…

计组原理:系统概论与基本组成

系统概论与基本组成 系统概论硬件软件 计算机系统的层次结构系统复杂性的管理方法1&#xff1a;抽象 计算机的基本组成冯诺依曼计算机系统复杂性的管理方法 2&#xff1a;&#xff08;3’Y&#xff09; 计算机的工作步骤上机前的准备&#xff1a;计算机的解题过程存储器的基本组…

AI教我学编程之C#类的实例化与访问修饰符

前言 在这篇文章中&#xff0c;我将带大家深入了解C#编程语言的核心概念&#xff0c;包括类的实例化、访问修饰符的应用&#xff0c;以及C#中不同数据类型的默认值。我会通过逐步分析和具体实例&#xff0c;详细解释如何在C#中正确创建和操作对象&#xff0c;并探讨如何通过访…

维基百科推广的12种方法帮你建立强大的品牌-华媒舍

维基百科是全球最大、最权威的多语言网络百科全书。它是许多人搜索信息、获取知识的首选平台&#xff0c;也是许多品牌建立强大影响力的重要途径。本文将介绍维基百科推广的12种方法&#xff0c;帮助你在维基百科上建立强大的品牌形象。 1. 准备工作 在开始维基百科推广之前&a…

IDEA怎么用Devtools热部署

IDEA怎么用Devtools热部署 大家知道在项目开发过程中&#xff0c;有时候会改动代码逻辑或者修改数据结构&#xff0c;为了能使改动的代码生效&#xff0c;往往需要重启应用查看改变效果&#xff0c;这样会相当耗费时间。 重启应用其实就是重新编译生成新的Class文件&#xff0…

机器学习:何为监督学习和无监督学习

目录 一、监督学习 &#xff08;一&#xff09;回归 &#xff08;二&#xff09;分类 二、无监督学习 聚类 一、监督学习 介绍&#xff1a;监督学习是指学习输入到输出&#xff08;x->y&#xff09;映射的机器学习算法&#xff0c;监督即理解为&#xff1a;已知正确答案…

C语言总结十一:自定义类型:结构体、枚举、联合(共用体)

本篇博客详细介绍C语言最后的三种自定义类型&#xff0c;它们分别有着各自的特点和应用场景&#xff0c;重点在于理解这三种自定义类型的声明方式和使用&#xff0c;以及各自的特点&#xff0c;最后重点掌握该章节常考的考点&#xff0c;如&#xff1a;结构体内存对齐问题&…

C++PythonC# 三语言OpenCV从零开发(5):ROI截取

文章目录 前言ROI测试图片部分区域截取CCsharpPython 颜色区域分割CCsharpPython 颜色通道合并CCsharpPython 总结 前言 C&Python&Csharp in OpenCV 专栏 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程&#xff08;附带课程课件资料课件笔记&#xff09…