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,一经查实,立即删除!

相关文章

javascript设计模式-装饰者

装饰者 基本实现 是一种为对象增加我的技术,它并不使用创建新子类手段,一切都在动态完成。这个过程相对于使用者来说是透明的。透明地把对象包装在具有同样接口的另一个对象之中。 比如可以动态的为自行车对象添加可选的特色配件上。比如添加4个选件&…

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系统分为内核版和发行版 内核…

在线检测和离线检测的区别?

问题描述:在线检测和离线检测的区别? 问题解答: "在线检测"和"离线检测"是两种不同的数据或系统处理方式,主要区别在于处理的时机和方式: 在线检测(Online Detection)&am…

什么是UML?有什么用?

2、什么是UML?有什么用? UML 是 Unified Model Language的缩写,中文是统一建模语言,是由一整套图表组成的标准化建模语言。 UML 是一种统一建模语言,一种图标式语言(画图的) UML 不是只有 Java 中使用&…

Unity开发授权系统

Unity开发授权系统 引子 因为有些客户尾款到账不及时,因此研究了一套授权系统,当授权到期后,系统就提示软件授权已到期,不能继续使用云云,这样方便尾款的收回。 大体需求就是 时间相关性,可以自由设置授…

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

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 自定义类型 六、定…

测试开源C#人脸识别模块ViewFaceCore(6:视频活体检测)

之前的文章介绍ViewFaceCore模块的FaceAntiSpoofing类支持单帧活体检测(AntiSpoofing函数)及视频活体检测(AntiSpoofingVideo函数),视频活体检测时从摄像头中抓取一帧图片进行检测,当检测结果状态为Detecti…

使用阿里云服务器自建数据库配置多大合适?

阿里云服务器配置如何选择?用于自建数据库可以第七代云服务器ECS计算型c7、通用型g7或内存型r7实例,企业级独享型云服务器,CPU采用第三代Intel Xeon可扩展处理器(Ice Lake),基频2.7 GHz,全核睿频…

MySQL中对日期时间的处理

⭕️前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家(点击跳转到网站)⭕️ MySQL针对日期的处理 日期函数 SELECT CURDATE() -- 输出当前日期:2000-01-01 SELECT CURTIME() -- 输出当前时间&a…

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

代码随想录二刷 &#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…

SpringMVC- ThreadLocal变量的注意点

基本介绍 在Web应用中&#xff0c;尤其是在使用Spring框架或类似的服务器端Java技术时&#xff0c;ThreadLocal 是一种常用的方式来存储每个请求的用户信息或上下文数据。然而&#xff0c;由于Web服务器通常使用线程池来处理请求&#xff0c;因此理解和正确使用ThreadLocal变得…

【Alibaba工具型技术系列】「EasyExcel技术专题」实战研究一下 EasyExcel 如何从指定文件位置进行读取数据

实战研究一下 EasyExcel 如何从指定文件位置进行读取数据 EasyExcel的使用背景EasyExcel的时候痛点EasyExcel对比其他框架 EasyExcel的编程模式EasyExcel读取的指定位置导入数据的流程表头校验invokeHeadMap()方法 数据处理invoke()方法 执行中断hasNextdoAfterAllAnalysed()方…

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

阿里云国外服务器优惠活动「全球云服务器精选特惠」&#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;实现学生成绩信息管理工作流程的系统化、规范化和自动化。现在我国中学的学生…