【Python】继承会遇到的问题

  1. 单继承和多继承在python中的区别和应用场景
    • 单继承指的是一个子类只继承自一个父类。这简化了继承关系,使得代码易于理解和维护。大多数情况下,单继承足以处理常见的场景,如扩展基类的功能或者覆盖某些方法。
    • 多重继承允许在一个类同时继承多个父类的属性和方法。python也支持多重继承,这提供了极大的灵活性,允许创建更复杂的关系和行为。然而,他也带来了更高的复杂度和潜在的冲突,比如当多个父类有同名方法是的决策问题。多重继承长用于需要从多个源继承代码的情况,比如使用混合(Mixin)来组合多个类的功能
  2. 在子类中保留父类功能的同时添加或者修改功能
    • 使用super() 函数可以在子类中调用父类方法,这样即保留了父类的功能,有可以在子类中添加或者修改功能。这种方式常用于初始化的过程中确保父类也被正常初始化。或者在重写方法是扩展父类的行为
# 示例
class Vehicle:def __init__(self, brand, model):self.brand = brandself.model = modeldef describe(self):return f"This is a {self.brand} {self.model}."class Car(Vehicle):def __init__(self, brand, model, horsepower):super().__init__(brand, model)  # 使用super()调用父类的构造函数self.horsepower = horsepowerdef describe(self):# 使用super()调用父类的describe()方法,并添加额外的信息original_description = super().describe()return f"{original_description} It has {self.horsepower} horsepower."# 创建一个Car实例
my_car = Car("Tesla", "Model S", 670)# 调用重写后的describe方法
print(my_car.describe())
  1. Python中的继承解析顺序(MRO)及其对多重继承的影响
    • MRO的作用:当在一个类的实力上调用方法或者访问属性的时候,Python需要确定从那个类中获取该方法或者属性。如果使用的是多重继承,即一个类继承多个父类,这个查找过程可能会变得复杂。MRO就是python用来决定这种情况下如何进行查找的规则。
    • MRO的计算:python中的MRO是根据C3线性化算法计算的。这个算法的目的是保证子类总是在父类之前出现,且保持父类的声明顺序。从Python2.3开始,所有的新式类都继承object的类,都是用这种算法来决定MRO
    • 如何查看MRO:可以使用类的“mro”属性或者内置的mro()方法来获取任何类的mro列表,这方返回一个类包含和他所有的父类的元组,按照方法解析顺序排列
    • 如何理解MRO
      • 线性化:MRO为类和他的基类提供了一个明确的线性顺序。这意味着Python解释器在查找方法或者属性的时候有一个明确的清晰的路径
      • 保证一致性:无论从哪个类继承,MRO都保证了一致性,确保了在复杂的继承关系中,方法调用的行为是可预测的
      • 解决了多重继承的问题:通过C3线性算法,Python的MRO帮助解决了多重继承中可能遇到的复杂情况,如菱形继承(钻石问题)
class A:passclass B(A):passclass C(A):passclass D(B, C):passprint(D.__mro__)
print(D.mro())
# 输出结果:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
  1. 解决钻石问题
    • 钻石问题或者称之为菱形继承发生在多重继承的场景中,当两个父类继承自同一个祖先类,而子类同时继承这两个父类的时候,Python通过C3线性化解决了这个问题,确保每个类在MRO中只出现一次,并且父类的顺序得到了正确的维护。
  2. 接口与抽象类在python中的实现
    • 概念上的区别:
      • 抽象类:通常用于定义一个基本的模板,它可以包含一些基础的方法实现。抽象类可以有抽象方法和非抽象方法。抽象类的主要目的是被其他类继承,并提供一部分实现。
      • 接口:是一种特殊的抽象类,完全没有方法实现,只定义方法的签名,接口定义了一套协议或者行为规范,任何实现接口的类都必须实现接口中的所有方法
    • 使用场景上的区别:
      • 放你想要多个类按照相同的方式行动,但他们之间没有共同的基础实现的时候,你应该使用接口。接口更关注行为的规范化,而不是实现共享
      • 当你想要定义一个类的部分或者全部实现,并希望子类基于这个定义进行扩展的时候,你应该使用抽象类。抽象类允许你定义一些子类必须实现的抽象方法,同时提供其他方法的默认实现
    • 在Python中的具体实现
      • 尽管Python的abc模块让抽象类和接口类在技术上看起来很相似,但你可以通过他们的用途和定义来区分
      • 使用只包含“@abstractmethod”的类作为接口,意味着任何继承该类的子项都必须实现所有定义的方法。
      • 使用即包含“@abstractmethod”有包含常规方法的类作为抽象类,提供一个或者多个方法的默认实现,要求子类实现剩余的抽象方法
# 抽象类示例
from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef area(self):pass@abstractmethoddef perimeter(self):passclass Rectangle(Shape):def __init__(self, width, height):self.__width = widthself.__height = heightdef area(self):return self.__width * self.__heightdef perimeter(self):return 2 * (self.__width + self.__height)r = Rectangle(5, 10)
print(r.area())  # 输出:50
print(r.perimeter())  # 输出:30
# 接口类示例:
from abc import ABC, abstractmethodclass IWorker(ABC):@abstractmethoddef work(self):passclass Engineer(IWorker):def work(self):print("Solving problems")class Manager(IWorker):def work(self):print("Managing projects")engineer = Engineer()
engineer.work()  # 输出:Solving problemsmanager = Manager()
manager.work()  # 输出:Managing projects
  1. 多态性及其在继承中的作用
    • 多态性是面向对象编程中的一个核心概念,他指的是能够使用相同的接口对不同的数据类型进行操作。在继承中,多态性允许子类以自己的方式实现父类或者接口中定义的方法。意味着即使每个子类的行为可能不同,使用父类类型的应用调用这些方法时候,具体调用哪个类的方法将根据对象的实际类型在运行时决定
    • 多态性的作用
      • 提高代码的可复用性:通过多态,可以编写更通用的代码,这些代码可以与多种数据类型一起工作,而不是仅限于一个特定的类型
      • 提高代码的可扩展性:多态性使得当新增加子类时候,原有的代码无需修改或者仅需要少量修改即可适应新的数据类型,从而简化了系统的扩展。
      • 增强了代码的可维护性:多态性通过减少代码的重复和提高代码的抽象层次,使得代码更加易于理解和维护
      • 实现接口的多种实现:在设计模式中,多态性常常用于实现一个接口的多种实现方式,使得程序可以在运行是动态的选择最适合的实现
    • 多态性的实现
      • 在Python中,多态是隐式的提供,因为Python是动态语言,不需要显示的通过继承或者接口来实现多态性。
# 示例
class Bird:def fly(self):print("Some birds can fly.")class Sparrow(Bird):def fly(self):print("Sparrow flies low.")class Eagle(Bird):def fly(self):print("Eagle flies high.")# 使用同一个接口(fly方法)处理不同类型的对象
def let_bird_fly(bird):bird.fly()sparrow = Sparrow()
eagle = Eagle()let_bird_fly(sparrow)  # 输出: Sparrow flies low.
let_bird_fly(eagle)  # 输出: Eagle flies high.
  1. 使用组合代理继承解决特定设计问题
    • 在面向对象设计中,组合优于继承是一个常见的原则,意味着使用组合来组织或者复用代码比使用继承更加灵活。这个原则鼓励开发者在设计软件是考虑组合对象来实现功能,而不是通过严格的继承结构。使用组合可以减少代码的耦合度,增强代码的复用性,提供系统的灵活性和可维护性
    • 组合的优点
      • 提高代码的复用性:组合允许你将功能封装在不同的对象中,然后再多个地方复用这些对象
      • 减少类间的耦合,使用组合可以减少类直接的直接以来,因为组合对象通常是通过接口与外部世界教书,而不是通过继承获得的功能。
      • 提高代码的灵活性:通过替换或者修改内部的组合对象,额可以轻松改变对象的行为,而不需要修改类的继承结构
      • 简化系统设计:组合可以帮助避免创建复杂的继承关系,使系统设计更加简介和易于理解
# 使用组合实现日志功能
class Logger:def log(self, message):print(f"Log: {message}")class Calculator:def __init__(self):self.logger = Logger()def add(self, a, b):result = a + bself.logger.log(f"Adding {a} + {b} = {result}")return resultclass Printer:def __init__(self):self.logger = Logger()def print_document(self, document):self.logger.log(f"Printing document: {document}")Calculator().add(1, 3)
Printer().print_document("asd")
  1. 在子类中重写方法时决定是否调用父类方法
    • 在子类中重写方法时,是否嗲用父类方法取决于子类方法的目的。如果子类方法皆在完全替换父类方式,则可能不需要调用父类的方法。如果子类方法只是扩展或者修改父类方法的行为,则应该使用super()调用父类的方。
class A:def do_something(self):print("Method defined in A")class B(A):def do_something(self):print("Method defined in B")class C(A):def do_something(self):print("Method defined in C")class D(B, C):def do_something(self):super().do_something()  # 根据MRO决定调用B或CA.do_something(self)    # 直接调用A的方法
  1. 所有Python类继承自object类的特殊意义
    • 在python中,所有的新式类都隐式地继承自“object”类。这为所有的对象提供了一组基本方法,包括"str,repr"等这种设计确保了所有类都共享一组通用的基础功能,促进了一致性和可预测性
  2. 说一下继承好处和潜在的缺点
  • 好处:包括代码重用,逻辑封层和规范化。继承允许子类复用父类的方法或者属性,简化的代码的维护和扩展
  • 潜在缺点:包括过度使用继承可能导致复杂和脆弱的设计。如果继承层次过深或者设计不当,可能会导致代码难以理解和维护。此外,过度依赖继承可能限制了代码的灵活性,因为子类与父类之间紧密耦合。

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

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

相关文章

m4v是什么文件格式?m4v视频用什么软件打开?

m4v文件格式的诞生可追溯到苹果公司。作为数字媒体领域的先锋&#xff0c;苹果在iTunes商店中为视频内容引入了m4v格式。其初衷是为了在保证视频质量的同时&#xff0c;通过管理系统&#xff0c;实现对数字内容的保护。这使得m4v成为iOS和macOS平台上广泛使用的视频格式。 M4V的…

工具精灵--超级好用的在线工具网站

工具精灵是一个超级好用的在线工具网站&#xff0c;它有这些功能&#xff1a;json格式化、xml格式化、markdown在线编辑、sql格式化、json转Java、xml转Java等。 虽然有很多这种类似的网站了&#xff0c;但它们并不好用&#xff0c;很粗糙。工具精灵超级好用&#xff0c;细节方…

为什么要为 App 应用加固 ?如何为 App 应用加固 ?

一&#xff1a;为什么要为 App 应用加固 来看下 腾讯开放平台 官方的解释说明 若应用不做任何安全防护&#xff0c;极易被病毒植入、广告替换、支付渠道篡改、钓鱼、信息劫持等&#xff0c;严重侵害开发者的利益。 App 加固后&#xff0c;可以对应用进行安全防护&#xff0c;防…

代码随想录三刷day30

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣122. 买卖股票的最佳时机 II二、力扣55. 跳跃游戏三、力扣45. 跳跃游戏 II四、力扣1005.K次取反后最大化的数组和 前言 大家会发现本周的代码其实都简单…

回归测试?

1. 什么是回归测试&#xff08;Regression Testing&#xff09; 回归测试是一个系统的质量控制过程&#xff0c;用于验证最近对软件的更改或更新是否无意中引入了新错误或对以前的功能方面产生了负面影响&#xff08;比如你在家中安装了新的空调系统&#xff0c;发现虽然新的空…

GEE高阶案例——利用eemont进行ee.Number对象类的运算(加减成熟运算公式)

本教程的主要目的是利用eemont包对数字对象进行分析 代码 !pip install eemont !pip install geemapimport ee, eemont, geemap import geemap.colormaps as cm 进行EE验证 验证并初始化地球引擎和地球地图。 Map geemap.Map() 让我们定义一些 ee.Number 对象作为近红外…

抛弃Superhuman?这些替代方案让你眼前一亮!

Superhuman是一个极好的人工智能工具在电子邮件助理领域。根据SimilarWeb的最新统计&#xff0c;它在全球网站排名中排名第21980位&#xff0c;月访问量为1751798。然而市场上还有许多其他优秀的选择。为了帮助您找到最适合您需求的解决方案&#xff0c;我们为您精心挑选了10种…

项目性能优化—使用JMeter压测SpringBoot项目

我们的压力测试架构图如下&#xff1a; 配置JMeter 在JMeter的bin目录&#xff0c;双击jmeter.bat 新建一个测试计划&#xff0c;并右键添加线程组&#xff1a; 进行配置 一共会发生4万次请求。 ctrl s保存&#xff1b; 添加http请求&#xff1a; 配置http请求&#xff1a;…

免费开源、支持自建服务的团队协作、个人学习文档管理系统

大家好&#xff0c;我是小麦。今天来给大家分享的是几款个人使用过的免费、开源、适合团队协作的文档管理工具&#xff0c;并且是完全支持自己搭建服务的文档管理系统。 相信大家在学习、办公等场景下对文档管理工具使用的场景是比较多的&#xff0c;例如技术开发手册、个人学…

SpringBoot(数据库操作 + druid监控功能)

文章目录 1.JDBC HikariDataSource&#xff08;SpringBoot2默认数据源&#xff09;1.数据库表设计2.引入依赖 pom.xml3.配置数据源参数 application.yml4.编写一个bean&#xff0c;映射表5.编写测试类来完成测试1.引入依赖 pom.xml2.使用JdbcTemplate进行测试3.成功&#xff0…

【C语言】打印闰年

输⼊⼀个年份year&#xff0c;判断year是否是闰年 闰年判断的规则&#xff1a; 1&#xff0c; 能被4整除并且不能被100整除是闰年 2&#xff0c;能被400整除是闰年 结合起来如下&#xff1a; if ((year % 4 0 && year % 100 ! 0) || (year % 400 0)) 代码如下&…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的交通信号灯识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;本研究详细介绍了一种采用深度学习技术的交通信号灯识别系统&#xff0c;该系统集成了最新的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等早期算法进行了性能评估对比。该系统能够在各种媒介——包括图像、视频文件、实时视频流及批量文件中——准确地…

Python从COCO数据集中抽取某类别的数据

1、问题描述 今天需要训练一个人工智能检测模型&#xff0c;用于检测图片或视频中的人。自行收集训练数据费时费力&#xff0c;因而选择从公开数据集COCO中进行抽取。 2、数据准备 2.1 下载 COCO2017 数据集 train:http://images.cocodataset.org/zips/train2017.zip valid…

2023年蓝桥杯省赛——幸运数字

目录 题目链接&#xff1a;0幸运数字 - 蓝桥云课 (lanqiao.cn) 解法 思路 高级思路 总结 题目链接&#xff1a;0幸运数字 - 蓝桥云课 (lanqiao.cn) 解法 首先是我写了差不多一个小时的解法&#xff0c;裂开了&#xff0c;为什么我如此废物 思路 寻找第2023个在二进制、八…

http协议的历史与基本概念

文章目录 历史和发展起源&#xff1a;HTTP/0.9&#xff08;1991年&#xff09;&#xff1a;HTTP/1.0&#xff08;1996年&#xff0c;RFC 1945&#xff09;&#xff1a;HTTP/1.1&#xff08;1997年&#xff0c;RFC 2068&#xff1b;1999年更新为RFC 2616&#xff09;&#xff1a…

「连载」边缘计算(三十三)03-15:边缘部分源码(源码分析篇)

&#xff08;接上篇&#xff09; 初始化porxy&#xff0c;具体如下所示。 KubeEdge/edgemesh/pkg/proxy/proxy.go // Init: init the proxy. create virtual device and assign ips, etc.. func Init() { go func() { unused make([]string, 0) addrByService &addrTab…

【MIT 6.S081】2020, 实验记录(9),Lab: file system

目录 Task 1&#xff1a;Large filesTask 2&#xff1a;Symbolic links2.1 增加一个系统调用 symlink2.2 新增文件类型2.3 新增 NOFOLLOW 标志位2.4 实现 sys_symlink 系统调用2.5 修改 sys_open 函数2.6 测试 Task 1&#xff1a;Large files 现在的 xv6 系统中&#xff0c;一…

算法——贪心算法

《算法图解》——贪心算法 # 首先创建一个表&#xff0c;包含所覆盖的州 states_needed set([mt,wa,or,id,nv,ut,az]) # 传入一个数组&#xff0c;转换成一个集合#可供选择的广播台清单 stations {} stations[kone] set([id,nv,ut]) #用集合表示想要覆盖的州&#xff0c;且不…

线程的通俗解释

------------------------------------------------------------ author: hjjdebug date: 2024年 03月 17日 星期日 17:04:47 CST descpriton: 线程的通俗解释 ------------------------------------------------------------ 目录: 1. 什么是线程? 2. 线程函数长…

EMQX 4.0和EMQX 5.0集群架构实现1亿MQTT连接哪些改进

EMQX 5.0水平扩展能力得到了指数级提升&#xff0c;能够更可靠地承载更大规模的物联网设备连接量。 在EMQX5.0正式发布前的性能测试中&#xff0c;我们通过一个23节点的EMQX集群&#xff0c;全球首个达成了1亿MQTT连接每秒100万消息吞吐&#xff0c;这也使得EMQX 5.0成为目前为…