编程新手必看,Python3中继承知识点及语法学习总结(28)

1、继承

在Python 3中,继承是面向对象编程的一个核心概念,它允许我们创建一个新的类(称为子类或派生类),该类继承另一个类(称为父类或基类)的属性和方法。通过这种方式,子类可以重用父类的代码,同时添加或覆盖自己的特定功能。

下面是一个简单的Python 3继承示例:

# 定义一个父类  
class Animal:  def __init__(self, name):  self.name = name  def speak(self):  print(f"{self.name} makes a sound")  # 定义一个子类,继承自Animal类  
class Dog(Animal):  def __init__(self, name, breed):  # 调用父类的构造函数  super().__init__(name)  self.breed = breed  def speak(self):  # 覆盖父类的speak方法  print(f"{self.name} barks")  # 创建一个Dog对象  
my_dog = Dog("Buddy", "Labrador")  
# 调用继承自父类的方法  
print(my_dog.name)  # 输出: Buddy  
# 调用子类覆盖的方法  
my_dog.speak()  # 输出: Buddy barks

在这个例子中,我们定义了一个Animal类作为父类,它有一个name属性和一个speak方法。然后,我们定义了一个Dog类作为子类,它继承了Animal类。在Dog类的构造函数中,我们使用super().init(name)来调用父类的构造函数,并初始化name属性。然后,我们添加了一个breed属性,并覆盖了speak方法,使其更适合狗的行为。
通过继承,我们可以轻松地在子类中重用父类的代码,并在需要时添加或修改功能。这使得代码更加模块化和可维护。

2、继承的优缺点

继承是面向对象编程(OOP)的一个核心特性,它允许我们创建基于现有类的新类,从而实现代码的重用和扩展。然而,就像其他编程技术一样,继承也有其优点和缺点。
继承的优点:
代码重用:继承允许子类直接使用父类的属性和方法,从而避免了重复编写相同的代码。这有助于减少代码的冗余和提高代码的可维护性。
扩展性:子类可以在继承父类的基础上添加新的属性和方法,从而扩展父类的功能。这使得我们能够构建更加复杂和灵活的软件系统。
多态性:通过继承,我们可以实现多态性,即使用父类类型的引用指向子类对象,并调用子类实现的方法。这增强了代码的灵活性和可扩展性。
易于理解:继承关系通常反映了现实世界中的“is-a”关系,例如“狗是动物”这样的关系。这种关系使得代码更加直观和易于理解。
继承的缺点:
破坏封装性:继承可能会破坏封装性,因为子类可以访问和修改父类的内部状态。这可能导致父类内部的实现细节被暴露给子类,增加了代码的耦合度。
层次结构僵化:过度使用继承可能导致类的层次结构变得僵化。一旦一个类被设计为继承自另一个类,就很难改变这种关系。这可能会限制代码的灵活性和可维护性。
继承爆炸:当类层次结构过于复杂时,可能会导致继承爆炸的问题。这意味着一个子类可能继承了许多不必要的属性和方法,使得代码难以管理和维护。
多重继承的复杂性:虽然Python支持多重继承,但多重继承可能导致复杂的类关系,使得代码难以理解和调试。在处理多重继承时,需要特别小心以避免出现冲突和不可预测的行为。
为了克服继承的缺点,可以考虑使用其他面向对象编程技术,如组合(composition)、接口(interface)和抽象类(abstract class)等。这些技术可以在一定程度上替代继承,提供更加灵活和可维护的代码结构。在实际编程中,应根据具体情况权衡利弊,选择合适的面向对象编程技术。

3、多继承

在Python中,多继承允许一个类继承自多个父类,从而可以获取多个父类的属性和方法。这提供了更大的灵活性和代码重用,但也可能导致一些复杂性和潜在的问题,比如方法解析顺序(Method Resolution Order,MRO)和潜在的命名冲突。
下面是一个Python中多继承的简单示例:

# 定义两个父类  
class ParentA:  def feature_a(self):  print("Feature from ParentA")  class ParentB:  def feature_b(self):  print("Feature from ParentB")  # 定义一个子类,继承自ParentA和ParentB  
class Child(ParentA, ParentB):  def child_feature(self):  print("Feature from Child")  
# 创建一个Child对象  
my_child = Child()  
# 调用从ParentA继承的方法  
my_child.feature_a()  # 输出: Feature from ParentA  
# 调用从ParentB继承的方法  
my_child.feature_b()  # 输出: Feature from ParentB  
# 调用子类自己的方法  
my_child.child_feature()  # 输出: Feature from Child

在这个例子中,Child类继承自ParentA和ParentB。因此,Child类的对象可以访问ParentA和ParentB中的方法,以及它自己的方法。
然而,当子类需要覆盖父类中的方法时,或者在多个父类中存在相同名称的方法时,就可能出现一些问题。Python使用一种称为方法解析顺序(MRO)的算法来确定在调用方法时应该使用哪个父类中的版本。MRO是动态计算的,通常基于类的继承层次结构来决定。
此外,命名冲突也是多继承中需要注意的问题。如果两个父类中有相同名称的属性或方法,并且子类没有覆盖它们,那么子类将继承第一个父类中的版本(根据MRO的顺序)。如果需要从另一个父类访问该方法,可以通过调用super()或者使用类名直接访问。
为了避免多继承带来的复杂性,通常建议:
尽可能使用单继承,只在必要时使用多继承。
如果使用多继承,确保对MRO有深入的理解,并仔细考虑类之间的关系。
使用接口或抽象基类来定义类的行为,而不是直接继承多个实现类。
当需要覆盖父类方法时,确保明确指定要覆盖哪个父类的方法,并考虑使用super()来调用父类的方法。

4、Python 子类继承父类构造函数说明

如果在子类中需要父类的构造方法就需要显式地调用父类的构造方法,或者不重写父类的构造方法。
子类不重写 init,实例化子类时,会自动调用父类定义的 init

class Father(object):def __init__(self, name):self.name=nameprint ( "name: %s" %( self.name) )def getName(self):return 'Father ' + self.nameclass Son(Father):def getName(self):return 'Son '+self.nameif __name__=='__main__':son=Son('python')print ( son.getName() )

输出结果为:

name: python
Son python

如果重写了__init__ 时,实例化子类,就不会调用父类已经定义的 init,语法格式如下:

class Father(object):def __init__(self, name):self.name=nameprint ( "name: %s" %( self.name) )def getName(self):return 'Father ' + self.nameclass Son(Father):def __init__(self, name):print ( "hi" )self.name =  namedef getName(self):return 'Son '+self.nameif __name__=='__main__':son=Son('python')print ( son.getName() )

运行结果

hi
Son Python

如果重写了__init__ 时,要继承父类的构造方法,可以使用 super 关键字:

super(子类,self).__init__(参数1,参数2....)

还有一种经典写法:

父类名称.__init__(self,参数1,参数2...)
class Father(object):def __init__(self, name):self.name=nameprint ( "name: %s" %( self.name))def getName(self):return 'Father ' + self.nameclass Son(Father):def __init__(self, name):super(Son, self).__init__(name)print ("hi")self.name =  namedef getName(self):return 'Son '+self.nameif __name__=='__main__':son=Son('Python')print ( son.getName() )

输出结果为:

name: Python
hi
Son Python

4、多个继承和单继承之间区别、

多个继承和单继承之间的主要区别在于它们如何处理类之间的层次关系和代码重用。下面是它们之间的一些主要区别:
单继承
定义:单继承是指一个子类只能继承自一个父类。
优点:
简单直观:类的层次结构清晰明了,易于理解。
较少的冲突:由于子类只继承自一个父类,所以发生方法名冲突的可能性较低。
更易于管理:代码结构相对简单,维护起来更为容易。
缺点:
代码重用限制:当多个类有相似的功能时,每个类都需要单独实现这些功能,无法直接共享代码。
多个继承
定义:多个继承允许一个子类继承自多个父类。
优点:
代码重用增强:子类可以继承多个父类的属性和方法,从而减少了重复代码的需要。
灵活性提高:子类可以组合多个父类的功能,创建出更复杂的类。
缺点:
复杂性增加:类的层次结构变得更加复杂,难以理解和管理。
方法名冲突:当多个父类中存在相同名称的方法时,子类必须明确决定使用哪个父类的方法,或者覆盖这些方法。

钻石问题(Diamond Problem):在某些情况下,当多个父类继承自同一个更远的祖先类,并且这些父类都覆盖了祖先类中的某个方法时,子类可能会遇到选择哪个父类版本的问题。虽然Python通过方法解析顺序(MRO)解决了这个问题,但它仍然增加了理解和维护的复杂性。
总结
单继承和多继承各有其优缺点,选择使用哪种方式取决于具体的应用场景和需求。在大多数情况下,单继承由于其简单性和易于管理的特点而被广泛使用。然而,在某些情况下,当需要组合多个类的功能时,多个继承可能会更加合适。无论使用哪种方式,都需要仔细考虑类的设计和继承关系,以确保代码的可读性、可维护性和可扩展性。

5、方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:

class Parent:        # 定义父类def myMethod(self):print ('调用父类方法')class Child(Parent): # 定义子类def myMethod(self):print ('调用子类方法')c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法

super() 函数是用于调用父类(超类)的一个方法。
输出结果为:

调用子类方法
调用父类方法

6、类属性与方法

类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定使用 self。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。
实例
类的私有属性实例如下:

lass JustCounter:__secretCount = 0  # 私有变量publicCount = 0    # 公开变量def count(self):self.__secretCount += 1self.publicCount += 1print (self.__secretCount)counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount)  # 报错,实例不能访问私有变量

输出结果为:

1
2
2
Traceback (most recent call last):File "test.py", line 16, in <module>print (counter.__secretCount)  # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'

类的私有方法实例如下:

class Site:def __init__(self, name, url):self.name = name       # publicself.__url = url   # privatedef who(self):print('name  : ', self.name)print('url : ', self.__url)def __foo(self):          # 私有方法print('这是私有方法')def foo(self):            # 公共方法print('这是公共方法')self.__foo()x = Site('菜鸟教程', 'www.runoob.com')
x.who()        # 正常输出
x.foo()        # 正常输出
x.__foo()      # 报错

以上实例执行结果:
在这里插入图片描述
类的专有方法:
init : 构造函数,在生成对象时调用
del : 析构函数,释放对象时使用
repr : 打印,转换
setitem : 按照索引赋值
getitem: 按照索引获取值
len: 获得长度
cmp: 比较运算
call: 函数调用
add: 加运算
sub: 减运算
mul: 乘运算
truediv: 除运算
mod: 求余运算
pow: 乘方

7、运算符重载

Python同样支持运算符重载,我们可以对类的专有方法进行重载,实例如下:

class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self,other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

运行结果

Vector(7,8)

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

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

相关文章

Linux下基本指令-掌握

目录 为什么要学命令行 Linux下基本指令-掌握 ls 指令 pwd命令 cd 指令 touch指令 mkdir指令&#xff08;重要&#xff09;&#xff1a; rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a; man指令&#xff08;重要&#xff09;&#xff1a; cp指…

ThingsBoard远程RPC调用设备

使用 RPC 功能 客户端 RPC 从设备发送客户端 RPC 平台处理客户端RPC 服务器端 RPC 服务器端RPC结构 发送服务器端RPC 使用 RPC 功能 ThingsBoard 允许您从服务器端应用程序向设备发送远程过程调用 (RPC)&#xff0c;反之亦然。基本上&#xff0c;此功能允许您向设备发送命…

【Flutter】自动生成图片资源索引插件二:FlutterAssetsGenerator

介绍 FlutterAssetsGenerator 插件 &#xff1a;没乱码&#xff0c;生成的图片索引命名是小驼峰 目录 介绍一、安装二、使用 一、安装 1.安装FlutterAssetsGenerator 插件 生成的资源索引类可以修改名字&#xff0c;我这里改成R 2. 根目录下创建assets/images 3. 点击image…

HPE Aruba Networking推出新一代Wi-Fi 7接入点 助力企业高效应对安全、AI与物联网挑战

HPE ArubaNetworking推出的全新Wi-Fi 7接入点&#xff0c;提供全面的AI就绪边缘IT解决方案&#xff0c;旨在为用户和物联网设备提供安全、高性能的连接服务&#xff0c;以实现数据的捕获和路由&#xff0c;从而满足AI训练和推理需求 休斯顿-2024年4月23日-慧与科技(NYSE: HPE)近…

Python浅谈清朝秋海棠叶版图

1、清朝疆域概述&#xff1a; 清朝是我国最后一个封建王朝&#xff0c;其始于1616年建州女真部努尔哈赤建立后金&#xff0c;此后统一女真各部、东北地区。后又降服漠南蒙古&#xff0c;1644年入关打败农民起义军、灭南明&#xff0c;削三藩&#xff0c;复台湾。后又收外蒙&am…

el-input-number 只能输入整数,最小值1,最大值5

<el-form-item label"排序" prop"name" > <el-input-number v-model"form.sort" placeholder"请输入唯一排序" :min1 :max"5" :precision"0" class"custom-input-number" /> </el-form-…

addr2line + objdump 定位crash问题

目录 背景 godbolt汇编工具 tombstone ARM平台汇编知识 寄存器介绍 常见汇编指令 函数入参及传递返回值过程 入参顺序 变参函数 虚函数表 典型问题分析过程 Crash BackTrace Addr2line objdump 拓展 为什么SetCameraId函数地址偏移是40(0x28) 参考 背景 最近在…

新兴游戏引擎Godot vs. 主流游戏引擎Unity和虚幻引擎,以及版本控制工具Perforce Helix Core如何与其高效集成

游戏行业出现一个新生事物——Godot&#xff0c;一个免费且开源的2D和3D游戏引擎。曾经由Unity和虚幻引擎&#xff08;Unreal Engine&#xff09;等巨头主导的领域如今迎来了竞争对手。随着最近“独特”定价模式的变化&#xff0c;越来越多的独立开发者和小型开发团队倾向于选择…

目前软件测试前景怎么样?有哪些机遇和挑战?

随着信息技术的快速发展&#xff0c;软件已经成为了我们生活中不可或缺的一部分。而软件的质量和稳定性也直接关系到用户的使用体验和企业的竞争力。因此&#xff0c;软件测试作为软件质量保证的重要环节&#xff0c;其前景也备受关注。 首先&#xff0c;从行业角度来看&#x…

javaEE--多线程学习-进程调度

进程调度不明白&#xff1f;看这一篇文章就够了&#xff0c;逻辑衔接严密&#xff0c;文末附有关键面试题&#xff0c;一个海后的小故事让你瞬间明白这里面的弯弯绕绕&#xff01; 目录 1.什么是进程&#xff1f; 2.进程控制块&#xff08;PCB&#xff09; 2.1 一个PCB就是一…

python中开发页面的两种方法:Qt Designer(PyQt图形化界面拖拽开发App界面)以及Django(开发Web应用框架)

一、开发独立的窗口&#xff0c;App的那种&#xff0c;可使用tkinter或者PyQt 使用PyQt时&#xff0c;里面有个工具Qt Designer&#xff0c;是一个可视化的界面设计工具&#xff0c;可以通过拖拽等方式来设计界面。下面就是Qt Designer的操作界面&#xff1a; 参考链接如下&am…

广播式自动相关监视(ADS-B)系统市场发展空间大 空中交通是其目前主要应用领域

广播式自动相关监视&#xff08;ADS-B&#xff09;系统市场发展空间大 空中交通是其目前主要应用领域 广播式自动相关监视&#xff08;ADS-B&#xff09;系统是一种基于全球卫星定位系统和利用空地、空空数据链实现交通监控和信息传递的空管监视系统。   ADS-B系统是一种航空…