当前位置: 首页 > news >正文

【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. 说一下继承好处和潜在的缺点
  • 好处:包括代码重用,逻辑封层和规范化。继承允许子类复用父类的方法或者属性,简化的代码的维护和扩展
  • 潜在缺点:包括过度使用继承可能导致复杂和脆弱的设计。如果继承层次过深或者设计不当,可能会导致代码难以理解和维护。此外,过度依赖继承可能限制了代码的灵活性,因为子类与父类之间紧密耦合。

相关文章:

【Python】继承会遇到的问题

单继承和多继承在python中的区别和应用场景 单继承指的是一个子类只继承自一个父类。这简化了继承关系&#xff0c;使得代码易于理解和维护。大多数情况下&#xff0c;单继承足以处理常见的场景&#xff0c;如扩展基类的功能或者覆盖某些方法。多重继承允许在一个类同时继承多个…...

相机模型Omnidirectional Camera(全方位摄像机)

1. 背景 大多数商用相机都可以描述为针孔相机&#xff0c;通过透视投影进行建模。然而&#xff0c;有些投影系统的几何结构无法使用传统针孔模型来描述&#xff0c;因为成像设备引入了非常高的失真。其中一些系统就是全方位摄像机。 有几种方法可以制作全向相机。屈光照相机(D…...

论文阅读——Align before Fuse

Align before Fuse: Vision and Language Representation Learning with Momentum Distillation image-text contrastive learning(ITC)用在单模态&#xff0c;masked language modeling (MLM) and image-text matching (ITM) 用在多模态。 单模态编码器的表示上引入了中间图像…...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Rating)

提供在给定范围内选择评分的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Rating(options?: { rating: number, indicator?: boolean }) 从API version 9开始&#…...

Unity中的网格创建和曲线变形

Unity中的网格创建和曲线变形 3D贝塞尔曲线变形贝塞尔曲线基础线性公式二次方公式三次方公式 Unity 实现3D贝塞尔曲线变形准备工作脚本概述变量定义 变量解析函数解析 获取所有子节点GetAllChildren 获取所有子节点UpdateBezierBend 控制点更新CalculateBezier Bezier 曲线公式…...

day0 3r文档docker部署

3R编码 | 3R教室 - 最好的数字游民学习与交流俱乐部! (3rcd.com) window安装wsl下载不下来&#xff0c;正好有个服务器&#xff0c;就用linux吧密钥长度不匹配&#xff0c;设置一下长度即可 文档启动不成功&#xff0c;单独下载了下nginx&#xff0c;docker pull nginx:latest …...

PSCA复位控制集成之复位信号

组件可能支持两种基本的复位类型。 • 冷复位&#xff1a;重置组件中的所有逻辑。用作上电复位。 • 热复位&#xff1a;重置组件中的大部分逻辑。通常&#xff0c;复位的范围是所有功能逻辑。不包括在热复位中的逻辑会随组件类型而变化&#xff0c;但通常会排除诸如调试和 R…...

C#,数值计算,数据测试用的对称正定矩阵(Symmetric Positive Definite Matrix)的随机生成算法与源代码

C.Hermite 1、对称矩阵 对称矩阵(Symmetric Matrices)是指以主对角线为对称轴,各元素对应相等的矩阵。在线性代数中,对称矩阵是一个方形矩阵,其转置矩阵和自身相等。1855年,埃米特(C.Hermite,1822-1901年)证明了别的数学家发现的一些矩阵类的特征根的特殊性质,如称为埃…...

EventWaitHandle 和 lock使用区别

EventWaitHandle 和 lock 语句在 C# 中都是用于线程同步的机制&#xff0c;但它们之间有着显著的区别和不同的使用场景。下面是它们之间的主要对比和区别&#xff1a; EventWaitHandle 定义&#xff1a;EventWaitHandle 是用于跨进程或跨线程同步的低级别同步原语。它允许一个…...

【图论】树链剖分

本篇博客参考&#xff1a; 【洛谷日报#17】树链剖分详解Oi Wiki 树链剖分 文章目录 基本概念代码实现常见应用路径维护&#xff1a;求树上两点路径权值和路径维护&#xff1a;改变两点最短路径上的所有点的权值求最近公共祖先 基本概念 首先&#xff0c;树链剖分是什么呢&…...

Requests教程-17-请求代理设置

上一小节我们学习了requests解决乱码的方法&#xff0c;本小节我们讲解一下requests设置代理的方法。 代理基本原理 代理实际上指的就是代理服务器&#xff0c; 英文叫作proxy server &#xff0c;它的功能是代理网络用户去取得网络信息。形象地说&#xff0c;它是网络信息的中…...

python内置函数 G

python内置函数 G Python 解释器内置了很多函数和类型&#xff0c;任何时候都能使用。 G 名称描述getattr从对象中获取属性值。globals返回当前全局符号表的字典。 getattr(object, name) getattr(object, name) getattr(object, name, default) getattr() 是 Python 中…...

深入了解 Spring boot的事务管理机制:掌握 Spring 事务的几种传播行为、隔离级别和回滚机制,理解 AOP 在事务管理中的应用

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…...

机械产品CE-MD认证测试项目介绍

机械产品CE-MD认证测试项目介绍 一、引言 随着欧洲市场的日益开放和全球化进程的加速&#xff0c;越来越多的机械产品进入欧洲市场。为确保这些产品的安全性和符合性&#xff0c;欧洲联盟&#xff08;EU&#xff09;引入了CE认证制度。同时&#xff0c;对于医疗器械类产品&…...

金融知识分享系列之:MACD指标精讲

金融知识分享系列之&#xff1a;MACD指标精讲 一、MACD指标二、指标原理三、MACD指标参考用法四、MACD计算步骤五、MACD分析要素六、根据快线DIF位置判断趋势七、金叉死叉作为多空信号八、快线位置交叉信号九、指标背离判断行情反转十、差离值的正负十一、差离值的变化十二、指…...

王道c语言-100元有几种换法

Description 一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换正好40张&#xff0c;且每种票子至少一张。问&#xff1a;有几种换法&#xff1f; #include <stdio.h> int main() {int count 0;int i, j, t, k, ret 0;for (i 1; i < 37; i) {for …...

c++野指针如何处理?

什么是野指针&#xff1f; 野指针指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同&#xff0c;野指针无法通过简单地判断是否为NULL避免&#xff0c;而只能通过养成良好的编程习惯来尽力减少&#xff0c;对野指针进行操作很容易造成程序错误。 野指针产生…...

关于大根堆,set重载运算符

题目描述 \,\,\,\,\,\,\,\,\,\,制定合理的日程能够帮助利用好时间进行加训&#xff0c;加训和加训。 \,\,\,\,\,\,\,\,\,\,新学期开始了&#xff0c;应该好好学习了&#xff01;凌晨两点整&#xff0c;加睡失败的你在为新一天的各项重要事件制定闹钟。 \,\,\,\,\,\,\,\,\,\, \,…...

Algae c++

描述 问题陈述 池塘中藻类的发展情况如下。 假设年初i水藻的总重量为xi​克。对于 i≥2000&#xff0c;下列公式成立&#xff1a; xi1​rxi​−D 给你r、D和x2000​。请依次计算 x2001​、...、x2010​ 并打印出来。 输入描述 输入内容由标准输入法提供&#xff0c;格式…...

开发常用的一些工具总结

开发常用的一些工具总结 记录一些常用的开发软件. Android 开发相关 : Android studio 安卓开发者必备的编辑器,也是我用过最好用的编辑器.还可以用来写JNI 和C.Android studio 插件 : GsonFormatLeakCanary 其他 VS Code :轻量级的开发工具,插件非常多,很好用,但是上手难度…...

k8s Yaml语法解析

YAML是一个类似 XML、JSON 的标记性语言。它强调以数据为中心&#xff0c;并不是以标识语言为重点。因而YAML本身的定义比较简单&#xff0c;号称"一种人性化的数据格式语言"。 YAML的语法比较简单&#xff0c;主要有下面几个&#xff1a; 1、大小写敏感 2、使用缩进…...

【晴问算法】提高篇—动态规划专题—最长公共子序列

题目描述 现有两个字符串s1​​​​与s2​&#xff0c;求s1​​​​与s2​​​​的最长公共子序列的长度&#xff08;子序列可以不连续&#xff09;。 输入描述 第一行为字符串s1​​&#xff0c;仅由小写字母组成&#xff0c;长度不超过100&#xff1b; 第一行为字符串s2​​​…...

Greetings

Problem - 1915F - Codeforces 题意 给一些(l,r)找到所有能够包含(l,r)的数目 引入 也就是找逆序对个数 要用到归并排序中的思想&#xff1a; //https://www.luogu.com.cn/problem/P1216 #include<iostream> #include<cstdio> #include<stack> #include…...

JS03-函数

函数 使用函数 // 函数声明function sayHi(){document.write(Hello!<br>)}for(let i 1; i < 6; i){// 函数调用sayHi()}函数封装 function getScore(arr){sum 0for( let i 0; i < arr.length; i){sum arr[i]}document.write(sum)}getScore([99, 66, 100])函数…...

MySQL | CRUD

目录 1. Create 2. Retrieve 2.1. SELECT列 2.1.1. 全列查询 2.1.2. 指定列查询 2.1.3. 查询字段为表达式 2.1.4. 为查询结果指定别名 2.1.5. 结果去重 2.2. WHERE条件 2.2.1. 年龄小于19的同学 2.2.2. id在2~3的同学 2.2.3. id为1和4的同学 2.2.4. 姓张的同学及张…...

【电路笔记】-MOSFET作为开关

MOSFET 作为开关 文章目录 MOSFET 作为开关1、概述2、MOSFET特性曲线2.1 截住区域2.2 饱和区域3、MOSFET作为开关的示例4、功率MOSFET电机控制5、P沟道MOSFET作为开关6、互补MOSFET作为开关电机控制器当 MOSFET 在截止区和饱和区之间工作时,MOSFET 是非常好的电子开关,用于控…...

SpringBoot+Vue项目(Vue3环境搭建 + 基础页面)

文章目录 1.项目基本介绍2.安装Node.js&#xff08;SSM部分安装过&#xff09;3.初始化前端工程1.创建一个文件夹 springboot_vue2.创建vue项目1.在刚才创建的文件夹下打开命令行&#xff0c;使用脚手架搭建项目2.选择手动配置3.选择三个4.选择vue35.选择路由模式6.选择包管理方…...

elementui el-table表格自动循环滚动【超详细图解】

效果如图 1. 当表格内容超出时&#xff0c;自动滚动&#xff0c;滚动到最后一条之后在从头滚动。 2. 鼠标移入表格中&#xff0c;停止滚动&#xff1b;移出后&#xff0c;继续滚动。 直接贴代码 <template><div><div class"app-container"><e…...

关于学习的一点粗浅见解

我们学习的每一个领域&#xff0c;大多都有着宽泛的知识面&#xff0c;那在学习过程中&#xff0c;我们是应该一开始就专钻一个方向(即深度)&#xff0c;还是应该先扩展知识面(即广度)&#xff1f;个人认为&#xff0c;应该先扩展知识面宽度&#xff0c;然后再精研某个方向&…...

[java基础揉碎]Object类详解

目录 equals方法: hashCode: toString: finalize: equals方法: 和equals对比 1.: 既可以判断基本类型&#xff0c;又可以判断引用类型 2.: 如果判断基本类型&#xff0c;判断的是值是否相等。示例: int i10; double d10.0; 3.:如果判断引用类型&#xff0c;判断的是地址是…...