Python进阶————面向对象高级


面向对象高级

  • 前言
  • 一、继承
    • 1.1. 单继承
    • 1.2. 多继承
    • 1.3. 方法重写
    • 1.4. 子类调用父类方法
      • 1.4.1 父类名.父类方法名()
      • 1.4.2 super().父类方法名()
    • 1.5. 多层继承
  • 二、封装
    • 2.1. 私有属性
    • 2.2. 私有方法
  • 三、多态
    • 3.1. 多态的条件
    • 3.2. 多态的定义
  • 四、面向对象的其他特性
    • 4.1. 对象属性
    • 4.2. 类属性
    • 4.3. 类方法
    • 4.4. 静态方法
  • 总结


前言

  • 接下来我们学习Python中的继承、封装、多态以及其他特性

一、继承

  • 面向对象中的继承: 指的是多个类之间的所属关系,即子类默认继承父类的属性和方法。

1.1. 单继承

语法

class 类名(父类名):代码...

一个摊煎饼的老师傅[master],在煎饼果子界摸爬滚打多年,研发了一套精湛的摊煎饼技术, 师父要把这套技术传授给他的唯一的最得意的徒弟[apprentice]。[初始化、无参]

# 1.定义师傅类
class Master(object):# 1.1 属性def __init__(self):self.kofu = '[传统方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 2.定义徒弟类  继承自Master
class Tudi(Master):pass# 3.实例化
xiaoming = Tudi()         
print(xiaoming.kofu)	  # [传统方法]
xiaoming.make_cake()	  # 使用[传统方法]摊煎饼

1.2. 多继承

  • 多继承就是:一个类同时继承了多个父类。

语法

class 类名(父类名1,父类名2,...):  # 多个父类代码...

小明是个爱学习的好孩子,想学习更多的摊煎饼果子技术,于是,在百度搜索到小吃学校[school],学习摊煎饼果子技术。

# 1.定义师傅类
class Master(object):# 1.1 属性def __init__(self):self.kofu = '[传统方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 2.定义学校类
class School(object):# 1.1 属性def __init__(self):self.kofu = '[学院派方法煎饼]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 3.定义徒弟类
class Tudi(School, Master):pass# 3.实例化
xiaoming = Tudi()
print(xiaoming.kofu)    # [学院派方法煎饼]
xiaoming.make_cake()    # 使用[学院派方法煎饼]摊煎饼

注意:当一个类有多个父类时,默认使用第一个父类的同名属性和方法。

1.3. 方法重写

  • 重写也叫作覆盖,就是当子类属性或方法与父类的属性或方法名字相同的时候,从父类继承下来的成员可以重新定义!

xiaoming 掌握了老师傅的技术后,自己潜心钻研出一套自己的独门配方的全新摊煎饼果子技术。

# 1.定义师傅类
class Master(object):# 1.1 属性def __init__(self):self.kofu = '[传统方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 2.定义学校类
class School(object):# 1.1 属性def __init__(self):self.kofu = '[学院派方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 3.定义徒弟类
class Tudi(School,Master):# 1.1 属性def __init__(self):self.kofu = '[xiaoming独创技术]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 3.实例化
xiaoming = Tudi()
print(xiaoming.kofu)   # [xiaoming独创技术]
xiaoming.make_cake()   # 使用[xiaoming独创技术]摊煎饼

当父类中跟子类中有同名方法的时候,子类可以重写父类方法,子类对象调用该方法的时候,优先使用自己的,用完再用父类的

1.4. 子类调用父类方法

  • 子类中仍想要保留父类的行为,则需要在子类中调用父类方法可以使用的以下两个方法:

1.4.1 父类名.父类方法名()

使用该方法的时候父类名.父类方法名(self) 括号中必须要有self

很多顾客都希望能吃到徒弟做出的有自己独立品牌的煎饼果子,也有学校配方技术的煎饼果子味道。

# 1.定义师傅类
class Master(object):# 1.1 属性def __init__(self):self.kofu = '[传统方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 2.定义学校类
class School(object):# 1.1 属性def __init__(self):self.kofu = '[学院派方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 3.定义徒弟类
class Tudi(School,Master):# 1.1 属性def __init__(self):self.kofu = '[独创技术]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 1.3 使用老师傅的技术def master_make_cake(self):Master.__init__(self)Master.make_cake(self)# 1.4 使用学校技术def school_make_cake(self):School.__init__(self)School.make_cake(self)# 3.实例化
xiaoming = Tudi()
print(xiaoming.kofu)         # [独创技术]
xiaoming.make_cake()	     # 使用[独创技术]摊煎饼
xiaoming.master_make_cake()  # 使用[传统方法]摊煎饼
xiaoming.school_make_cake()	 # 使用[学院派方法]摊煎饼

1.4.2 super().父类方法名()

使用该方法的时候,super后边必须加括号,且 父类方法名括号中啥也不能有

很多顾客都希望能吃到徒弟做出的有自己独立品牌的煎饼果子,也有学校配方技术的煎饼果子味道。

# 1.定义师傅类
class Master(object):# 1.1 属性def __init__(self):self.kofu = '[传统方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 2.定义学校类
class School(object):# 1.1 属性def __init__(self):self.kofu = '[学院派方法]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 3.定义徒弟类
class Tudi(School,Master):# 1.1 属性def __init__(self):self.kofu = '[独创技术]'# 1.2 方法def make_cake(self):print(f'使用{self.kofu}摊煎饼')# 1.3 使用老师傅的技术def master_make_cake(self):# 必须重新初始化父类的属性Master.__init__(self)super().make_cake()# 1.4 使用学校技术def school_make_cake(self):# 必须重新初始化父类的属性School.__init__(self)super().make_cake()# 3.实例化
xiaoming = Tudi()
print(xiaoming.kofu)         # [独创技术]
xiaoming.make_cake()	     # 使用[独创技术]摊煎饼
xiaoming.master_make_cake()  # 使用[传统方法]摊煎饼
xiaoming.school_make_cake()	 # 使用[学院派方法]摊煎饼

1.5. 多层继承

"""
多层继承介绍:概述:实际开发中, 类与类之间是可以多层继承的, 例如: 类A继承类B, 类B继承类C, 这就是: 多层继承.例如:A => 继承B => 继承C => 继承object
"""

N年后,小明老了,想要把“有自己的独立品牌,也有学院配方技术的煎饼果子味道”的所有技术传授给自己的徒弟。

# 1. 创建1个师傅类, 充当父类.
class Master(object):# 1.1 定义父类的 属性.def __init__(self):self.kongfu = '[古法煎饼果子配方]'# 1.2 定义父类的 行为, 表示: 摊煎饼.def make_cake(self):print(f'使用 {self.kongfu} 制作煎饼果子')# 2. 创建1个师傅类, 充当父类.
class School(object):# 2.1 定义父类的 属性.def __init__(self):self.kongfu = '[学院派煎饼果子配方]'# 2.2 定义父类的 行为, 表示: 摊煎饼.def make_cake(self):print(f'使用 {self.kongfu} 制作煎饼果子')# 3. 定义徒弟类, 继承自师傅类.
class Prentice(School, Master):# 3.1 定义本类(子类)的 属性.def __init__(self):self.kongfu = '[独创煎饼果子配方]'# 3.2 定义本类(子类)的 行为, 表示: 摊煎饼.def make_cake(self):        # 子类出现和父类重名且一模一样的函数, 称之为: 方法重写.print(f'使用 {self.kongfu} 制作煎饼果子')# 3.3 定义函数 make_master_cake(), 表示: 古法摊煎饼果子配方.def make_master_cake(self):# 前提(细节): 需要重新初始化一下父类的 属性.Master.__init__(self)# 调用Master#make_cake()Master.make_cake(self)# 3.4 定义函数 make_school_cake(), 表示: 黑马AI摊煎饼果子配方.def make_school_cake(self):# 前提(细节): 需要重新初始化一下父类的 属性.School.__init__(self)# 调用School#make_cake()School.make_cake(self)# 4. 定义徒孙类, 继承: 徒弟类.
class TuSun(Prentice):      # 继承关系:  TuSun => Prentice => School, Master => objectpass# 在main函数中测试
if __name__ == '__main__':# 4. 创建 徒孙类 的对象ts = TuSun()# 5. 调用父类的成员.print(f'属性: {ts.kongfu}')  # 属性: [独创煎饼果子配方]ts.make_cake()               # 使用 [独创煎饼果子配方] 制作煎饼果子ts.make_master_cake()        # 使用 [古法煎饼果子配方] 制作煎饼果子ts.make_school_cake()        # 使用 [学院派煎饼果子配方] 制作煎饼果子

二、封装

  • 在软件编程中,将属性和方法书写到类的里面的操作即为封装,封装可以为属性和方法添加私有权限。

2.1. 私有属性

  • 在Python中,可以为属性设置私有权限,即设置某个属性不继承给子类。

  • 设置私有权限的方式:在属性名前面加上两个下划线 __,

格式

"""
self.__属性名当设置了属性为私有属性后,那么我们只能在本类中通过self. 的方法来访问该属性如果在类外想要访问私有属性的话,必须通过公共方法才行
"""

代码如下(示例):

class Prentice(object):# 1.1 属性def __init__(self):self.kongfu = '[独创的煎饼果子配方]'# 私有的属性.self.__money = 500000         # 这个才是私有化的写法.# 1.2 对外提供公共的访问方式, 可以实现: 获取私有的变量, 以及给变量设置值.# 获取值.def get_money(self):return self.__money# 设置值def set_money(self, money):# 可以在这里对 money属性做判断, 但是没必要. 因为Python属于后端代码, 这里的钱肯定是前端传过来的, 而传过来的数据已经经过了前端的校验.# 换言之, 这里如果校验就属于 二次校验了.  实际开发中, 重要字段会做二次校验, 否者可以不做校验.# if money > 0:#     self.__money = money# else:#     self.__money = 0self.__money = money# 2. 定义徒孙类, 继承自徒弟类.
class TuSun(Prentice):pass# 在main函数中测试调用
if __name__ == '__main__':# 3. 创建徒孙类对象.ts = TuSun()# 4. 尝试访问父类的成员.# 父类的公共的 属性print(f'父类的属性: {ts.kongfu}') # 父类的属性: [独创的煎饼果子配方]print(f'父类的私有属性, 通过 公共的方式访问: {ts.get_money()}')  # 父类的私有属性, 通过 公共的方式访问: 500000# 通过父类的公共方式, 修改 父类的私有属性.ts.set_money(10)print(f'父类的私有属性, 通过 公共的方式访问: {ts.get_money()}')  # 父类的私有属性, 通过 公共的方式访问: 10

2.2. 私有方法

  • 在Python中,可以为方法设置私有权限,即设置某个方法不继承给子类。
  • 设置私有权限的方式:在方法名前面加上两个下划线 __

格式

"""
def __方法名(self):...当设置了属性为私有属性后,那么我们只能在本类中通过self. 的方法来访问该属性如果在类外想要访问私有属性的话,必须通过公共方法才行
"""

小明把煎饼果子技术传承给徒弟的同时,不想把自己的独创配方制作过程继承给徒弟,这时就要为制作独创配方这个方法设置私有权限。

# 1. 定义徒弟类, 有自己的属性 和 行为.
class Prentice(object):# 1.1 属性def __init__(self):self.kongfu = '[独创的煎饼果子配方]'# 私有的属性.# self.__money__ = 500000     # 这个不是私有, 就是变量名叫: __money__self.__money = 500000         # 这个才是私有化的写法.# 1.2 对外提供公共的访问方式, 可以实现: 获取私有的变量, 以及给变量设置值.# 获取值.def get_money(self):return self.__money# 设置值def set_money(self, money):self.__money = money# 1.3 行为def __make_cake(self):print(f'采用 {self.kongfu} 制作煎饼果子!')# 验证: 私有成员, 在本类中是可以直接访问的.print(f'私房钱为: {self.__money}')# 针对于父类的私有方法, 提供公共的访问方式(在其内部调用 私有化的方法即可)def my_make(self):# 调用私有化方法 __make_cake()self.__make_cake()# 2. 定义徒孙类, 继承自徒弟类.
class TuSun(Prentice):pass# 在main函数中测试调用
if __name__ == '__main__':# 3. 创建徒孙类对象.ts = TuSun()# 4. 尝试访问父类的成员.# 4.1 父类的 私有的 属性.print(f'父类的私有属性, 通过 公共的方式访问: {ts.get_money()}')# 通过父类的公共方式, 修改 父类的私有属性.ts.set_money(10)print(f'父类的私有属性, 通过 公共的方式访问: {ts.get_money()}')print('-' * 21)# 4.2 父类的 私有的 方法(行为).# ts.__make_cake()        # AttributeError, 父类私有成员(方法), 子类无法直接访问.# ts.make_cake()ts.my_make()

三、多态

3.1. 多态的条件

"""
1、有继承 (定义父类、定义子类,子类继承父类)
2、函数重写 (子类重写父类的函数)
3、父类引用指向子类对象 (子类对象传给父类对象调用者)
"""

3.2. 多态的定义

  • 多态,指的是:多种状态。比如:同样一个函数在不同的场景下有不同的状态。

代码演示如下

class Animal(object):def speak(self):print("animal 嗯嗯 ")passclass Dog(Animal):def speak(self):print('汪汪汪')class Cat(Animal):def speak(self):print('喵喵喵')# def make_noise(animal):
def make_noise(animal:Animal):animal.speak()if __name__ == '__main__':mydog = Dog()mycat = Cat()animal =  Animal()make_noise(mydog)     # 汪汪汪# make_noise(mycat)   # 喵喵喵# make_noise(animal)   # animal 嗯嗯pass

四、面向对象的其他特性

4.1. 对象属性

"""
对于属性,调用时有两种方式,如下:1、 self.对象属性名  # 类内部2、 对象名.对象属性名   # 类外部
"""

4.2. 类属性

"""
所谓类属性,指的就是类所拥有的属性,它被共享于整个类中(即都可以直接调用),格式如下:1、 类名.类属性名    # 推荐使用2、 对象名.类属性名"""

4.3. 类方法

  • 类方法,指的是类所拥有的方法,并需要使用[装饰器]@classmethod来标识其为类方法

同时一定要注意的是对于类方法的第一个参数必须是类对象,通常以cls作为第一个参数名,格式如下:

@classmethod
def 类方法名(cls):...# 调用时,格式如下:1、 类名.类方法名()    # 推荐使用2、 对象名.类方法名()

类方法一般和类属性配合使用,尤其是使用私有类属性时。

4.4. 静态方法

静态方法需要通过装饰器@staticmethod来来标识其为静态方法,且静态方法不需要多定义参数,格式如下:

@staticmethod
def 静态方法名():...# 调用时,格式如下:1、 类名.静态方法名    # 推荐使用2、 对象名.静态方法名

功能不变的时候使用静态方法


总结

  • 以上就是面向对象的封装、继承、多态的定义与代码演示。

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

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

相关文章

【学习笔记】卫星通信NTN 3GPP标准化进展分析(四)- 3GPP Release18内容

一、引言: 本文来自3GPP Joern Krause, 3GPP MCC (May 14,2024) Non-Terrestrial Networks (NTN) (3gpp.org) 本文总结了NTN标准化进程以及后续的研究计划,是学习NTN协议的入门。 【学习笔记】卫星通信NTN 3GPP标准化进展分析(一&#xff…

Codeforces Round 964 (Div. 4) A-E Java题解

比赛地址 Dashboard - Codeforces Round 964 (Div. 4) - Codeforces A题 签到题 给一个两位数 求各位上的数字和 直接对10取余加上本来的数除以10 // 注意类名必须为 Main, 不要有任何 package xxx 信息 // package Dduo; import java.io.*; import java.math.*; import j…

FFmpeg源码:av_rescale_rnd、av_rescale_q_rnd、av_rescale_q、av_add_stable函数分析

一、av_rescale_rnd函数 (一)av_rescale_rnd函数的声明 av_rescale_rnd函数声明在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的头文件libavutil/mathematics.h中: /*** Rounding methods.*/ enum AVRounding {…

【Android自定义控件】Kotlin实现滚动效果的数字加减控件

前言 因业务上的需要,在APP中点餐时要有商品数目增减操作,数目增减的过程中有翻动的动画效果展现。在Android中有多种方式可以实现,本篇文章记录通过自定义View结合控件的平移动画相结合来实现此需求。 需求分析 根据上图分析控件的实现过程以…

力扣763-划分字母区间(Java详细题解)

题目链接:763. 划分字母区间 - 力扣(LeetCode) 前情提要: 因为本人最近都来刷贪心类的题目所以该题就默认用贪心方法来做。 贪心方法:局部最优推出全局最优。 如果一个题你觉得可以用局部最优推出全局最优&#xf…

如何在 Vim 中显示行号

前言 Vim 是一款功能强大的文本编辑器,在 Linux、Mac 和 Windows 上都有广泛的应用。对于开发人员来说,能够快速查看代码行号是一个非常实用的功能,尤其是在进行调试或阅读长文件时。本文将介绍如何在 Vim 中开启和关闭行号显示。 开启行号…

【STM32】RS485

RS485是常见的串口接口。 大部分图片来源:正点原子HAL库课程 专栏目录:记录自己的嵌入式学习之路-CSDN博客 目录 1 串口、UART、TTL、RS232、RS422、RS485的关系 1.1 串口 1.2 UART、TTL、RS232、RS422、RS485 1.3 常见串口标准的比较 …

JS 如何判断是否是IE浏览器

例子 if(!!window.ActiveXObject || "ActiveXObject" in window){alert("抱歉,不支持IE浏览器!");return; }

亚马逊云技术深度解析与实战案例

亚马逊云技术深度解析与实战案例 引言 亚马逊云(Amazon Web Services, AWS)作为全球云计算技术的领导者,以其丰富的服务种类、强大的基础设施和持续的技术创新,为企业和个人开发者提供了前所未有的灵活性和扩展性。本文将深入探讨亚马逊云的核心技术,并通过一个具体的代…

vue el-tree主键id重复 添加自增id 以及原相同节点同步勾选 同步操作

树数据只提供了nodeId,且存在不同节点重复nodeId的问题,由于树组件的node-key需要唯一性,所有这个时候我们需要给数据添加自增id (延申问题:操作某个节点的时候,同步操作与他nodeId相同的节点)&…

【微机原理】v和∧区别

🌟 嗨,我是命运之光! 🌍 2024,每日百字,记录时光,感谢有你一路同行。 🚀 携手启航,探索未知,激发潜能,每一步都意义非凡。 在汇编语言和逻辑表达…

UE 【材质编辑】自定义材质节点

使用UE的材质编辑器,蓝图提供了大量的节点函数: 实际上,这是一段封装好的包含一串HLSL代码的容器。打开“Source/Runtime/Engine/Classes/Material”,可以看到很多不同节点的头文件: 照葫芦画瓢 以UMaterialExpressi…

★ 算法OJ题 ★ 力扣 LCR179 - 和为 s 的两个数字

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;小诗歌剧将和大家一起做一道双指针算法题--和为 s 的两个数字~ 目录 一 题目 二 算法解析 三 编写算法 一 题目 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 二 算法解析 …

MacOS使用FileZilla通过ssh密钥文件连接远程服务器(已解决)

需求描述 mac电脑,使用filezilla通过FTP连接远程服务器,使用ssh密钥文件代替密码。 版本信息 MacOS:Sonoma 14.5 M3芯片 FileZilla:3.66.5 在这里插入图片描述 连接 1. 创建站点 打开filezilla工具,右上角选择“文件 -> 站点管理器”,打开站点管理器弹窗。 2.…

2024“钉耙编程”中国大学生算法设计超级联赛(9)

传送门 1005 怪物猎人 如果全用 x 和 全用 y 攻击的轮次不同那么奇偶轮次都可以击败怪物&#xff1b;否则只有奇数轮次或者偶数轮次能够击败怪物。 #include <bits/stdc.h> using namespace std;#define int long longinline int read() {int x 0, f 1; char c get…

AI搜索:重塑信息获取的新纪元

在信息爆炸的时代&#xff0c;如何快速、准确地获取所需信息成为了每个人面临的挑战。传统的搜索引擎虽然在一定程度上解决了这一问题&#xff0c;但广告干扰、结果冗余、内容质量参差不齐等问题仍让用户体验大打折扣。随着AI技术的不断发展&#xff0c;AI搜索产品以其独特的优…

将工程内的组件 集成并发布到私有仓库以及后续联动运行(热启动)

将工程内的组件 发布到私有仓库 背景与简介 1、项目的数据 私有仓库地址&#xff1a; 【】 私有仓库账号/密码&#xff1a; 【】 组件包名称&#xff1a; 【ciec/ciec-component-pc】 组件包项目git地址&#xff1a;【 】 node版本&#xff1a;【】 2、文献链接 a)t b) 3、注意…

docker安装配置、docker命令

一、CentOS7安装docker 1、安装 Docker CE 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0c; CentOS 7 满足最低内核的要求&#xff0c;所以我们在CentOS 7安装Docker。 卸载旧docker 如果之前安装过旧版本的Docker&#xff0c;可以使用下面命令…

DFS、BFS、Union-Find:找出图中省份数量的最佳方法

题目理解 问题描述&#xff1a; 有 n 个城市&#xff0c;其中一些城市之间直接相连&#xff0c;另一些则不相连。如果城市 a 和城市 b 直接相连&#xff0c;且城市 b 和城市 c 直接相连&#xff0c;那么城市 a 和城市 c 间接相连。省份被定义为一组直接或间接相连的城市&…

美团2024秋招编程题:小美的red子序列数量之和

题目为&#xff1a; 小美有一个字符串&#xff0c;小美想知道这个字符串的所有连续子串中&#xff0c;red 子序列的数量之和。 子串是指从原字符串中&#xff0c;连续的选择一段字符组成的新字符串。 定义 red 子序列为从原字符串中从左到右依次取出r、e和d组成的新字符串。 …