Python面向对象的三大特征 - - 封装、继承、多态

news/2024/4/27 19:15:20/文章来源:https://blog.csdn.net/qq_41619571/article/details/129377012

目录

一、三大特征介绍

1、封装(隐藏)

2、继承

 3、多态

二、继承

1、子类扩展父类

1.语法格式

2.构造函数

2、类成员的继承和重写

1. 成员继承

2. 方法重写

3、查看类的继承层次结构

4、object根类

1.描述

2. dir() 查看对象属性(方法本质也是属性)

3. 重写 __str__() 方法

5、多重继承

 6、MRO方法解析顺序

7、super()获得父类定义 

三、多态

        1、多态描述

2、多态注意事项


一、三大特征介绍

1、封装(隐藏)

        隐藏对象的属性和实现细节,只对外提供必要的方法。相当于将“细节封装起来”,只对外暴露“相关调用方法”。
        通过“私有属性私有方法”的方式,实现“封装”。Python追求简洁的语法,没有严格的语法级别的“访问控制符”,更多的是依靠程序员自觉实现

2、继承

        继承可以让子类具有父类的特性,提高了代码的重用性。
        从设计上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进已有的算法

 3、多态

        多态是一种允许不同对象对相同消息作出响应的机制。在多态中,不同的对象可以具有相同的方法名称,但是它们的行为可能会有所不同。这样就可以通过一个通用的方法调用来处理多个不同的对象。多态可以提高代码的灵活性和可扩展性。

二、继承

1、子类扩展父类

1.语法格式

        Python支持多重继承,一个子类可以继承多个父类。继承的语法格式如下:

class 子类类名(父类1[,父类2,...]):类体

        如果在类定义中没有指定父类,则默认父类 object 类 。也就是说, object 是所有类的父类,里面定义了一些所有类共有的默认实现,比如: __new__()

2.构造函数

①. 子类不重写__init__,实例化子类时,会自动调用父类定义的 __init__

class Person:def __init__(self,name,age):print("Person的构造方法")self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)class Stedent(Person):passs1 = Stedent("张三",15)
print(dir(s1))
s1.say_age()'''
Person的构造方法
[... 'age', 'name', 'say_age']
张三 的年龄是: 15
None#查看Stedent类对象的所有属性、方法,已经包含了Person类'''

②. 子类重写了__init__时,实例化子类,就不会调用父类已经定义的__init__

class Person:def __init__(self,name,age):print("Person的构造方法")self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)class Stedent(Person):def __init__(self,name,age,score):self.name = nameself.age = ageself.score = score    #定义自己的方法s1 = Stedent("张三",15)
print(dir(s1))
s1.say_age()
print(s1.score)'''
*************运行报错***********
TypeError: __init__() missing 1 required positional argument: 'score'
此时因为没有继承父类“Person”的构造方法,所以报错,需要添加score参数'''#修改s1处代码
s1 = Stedent("张三",15,100)'''
[... 'age', 'name', 'say_age', 'score']
张三 的年龄是: 15
100
'''

③. 如果重写了 __init__  时,要使用父类的构造方法,可以使用 super  关键字,也可以使用如下格式调用:        父类名.__init__(self, 参数列表)

class Person:def __init__(self,name,age):print("Person的构造方法")self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)class Stedent(Person):def __init__(self,name,age,score):Person.__init__(self,name,age)print("Student的构造方法1")self.score = scores1 = Stedent("张三",15,100)
s1.say_age()
print(s1.score)'''
Person的构造方法
Student的构造方法1
张三 的年龄是: 15
100'''
class Person:def __init__(self,name,age):print("Person的构造方法")self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)class Stedent(Person):def __init__(self,name,age,score):super(Stedent,self).__init__(name,age)print("Student的构造方法1")self.score = scores1 = Stedent("张三",15,100)
s1.say_age()
print(s1.score)#结果和父类名方式一样

2、类成员的继承和重写

1. 成员继承

        子类继承了父类除构造方法之外的所有成员私有属性、私有方法也被继承

Python中私有属性“_“下划线   和  “__“双下划线的区别”

class Person:def __init__(self,name,age):print("Person的构造方法")self.name = nameself.__age = age'''将age属性私有'''def say_age(self):print(self.name,"的年龄是:",self.__age)class Stedent(Person):def __init__(self,name,age,score):super(Stedent,self).__init__(name,age)print("Student的构造方法1")self.score = scoredef say_score(self):print("我的分数",self.score)s1 = Stedent("张三",15,100)
s1.say_age()
s1.say_score()
print(dir(s1))'''
Person的构造方法
Student的构造方法1
张三 的年龄是: 15
我的分数 100
['_Person__age',...]
'''

2. 方法重写

        子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写

class Person:def __init__(self,name,age):self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)def say_name(self):print("我是",self.name)class Student(Person):def __init__(self,name,age,score):Person.__init__(self,name,age)self.score = scoredef say_score(self):    #自己定义的方法print(self.name,"的分数是:",self.score)def say_name(self):     #重写父类的方法print("你好,我是",self.name)s1 = Student("张三",15,85)
s1.say_score()
s1.say_name()
s1.say_age()'''
张三 的分数是: 85
你好,我是 张三        #已经重写了父类的方法
张三 的年龄是: 15
'''

3、查看类的继承层次结构

        通过类的方法 mro() 或者类的属性 __mro__ 可以输出这个类的继承层次结构

class A:pass
class B(A):pass
class C(B):passprint(C.mro())
#或者 print(C.__mro__)'''
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
'''
#依次C - B - A -object

4、object根类

1.描述

        object 类是所有类的父类,因此所有的类都有 object 类的属性和方法

2. dir() 查看对象属性(方法本质也是属性)

class Person:def __init__(self,name,age):self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)obj = object()
print(dir(obj))
s2 = Person("花非人陌",18)
print(dir(s2))

运行结果

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', 
'__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__']['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', 
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
'age', 'name', 'say_age']

从上面可以发现这样几个特点

class Person:def __init__(self,name,age):self.name = nameself.age = agedef say_age(self):print(self.name,"的年龄是:",self.age)s2 = Person("花非人陌",18)
print(type(s2.age))
print(type(s2.name))
print(type(s2.say_age))'''
运行结果
<class 'int'>
<class 'str'>
<class 'method'>
'''

①. Person 对象增加了六个属性:

        __dict__   __module__   __weakref__     age      name      say_age


②. object 的所有属性, Person 类作为 object 的子类,显然包含了所有的属性

③. 我们打印 age name say_age ,发现 say_age 虽然是方法,实际上也是属性。只不过,这个属性的类型是 method 而已。

3. 重写 __str__() 方法

. object 有一个 __str__() 方法,用于返回一个对于“对象的描述”。内置函数 str(对象) , 调用的就是__str__()

. __str__() 经常用于 print() 方法,帮助查看对象的信息。__str__() 可以重写

class Person:def __init__(self,name,age):self.name = nameself.__age = agedef __str__(self):'''将对象转化成一个字符串描述,一般用于print方法'''print("重写__str__方法")return "名字是:{0},年龄是{1}".format(self.name,self.__age)
p = Person("花非人陌",18)
print(p)
s = str(p)
print(s)'''
重写__str__方法            #重写了对象
名字是:花非人陌,年龄是18  #打印了返回值
重写__str__方法            #重写了对象并将返回值给了s
名字是:花非人陌,年龄是18
'''

5、多重继承

        Python支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父类”的特点。但是由于,这样会被“类的整体层次”搞的异常复杂,尽量避免使用。

class A:def aa(self):print("aa")
class B:def bb(self):print("bb")
class C(B,A):def cc(self):print("cc")
c = C()
c.cc()
c.bb()
c.aa()
print(C.mro())'''
输出结果:
cc
bb
aa
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
'''

类结构为:

 6、MRO方法解析顺序

        Python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左向右”按顺序搜索。
        MRO(Method Resolution Order):方法解析顺序。 我们可以通过 mro() 方法获得“类的层次结构”,方法解析顺序也是按照这个“类的层次结构”寻找的。
 

class A:def aa(self):print("aa")def say(self):print("say AAA!")class B:def bb(self):print("bb")def say(self):print("say BBB!")class C(B,A):        #B和A代表先后顺序,B优先于Adef cc(self):print("cc")c = C()
print(C.mro())    #打印层次结构
c.say()           #解释器寻找的方法是从左到右'''
执行结果:
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
say BBB!
'''

7、super()获得父类定义 

        super() 是一个内置函数,用于获取当前类的父类(或超类)的定义。它可以用来调用父类的方法、属性或构造函数

        在子类中,如果想要获得父类的方法时,我们可以通过 super() 来做。super() 代表父类的定义不是父类对象

        调用父类的构造方法:        super(子类名称,self).__init__(参数列表)

        例子:在构造函数和方法中使用 super() 函数来调用父类的方法或构造函数

class A:def __init__(self):print("A的构造方法")def say(self):print("A: ", self)print("say AAA")class B(A):def __init__(self):#A.__init__(self) 调用父类的say方法super(B, self).__init__()  # 调用父类的构造方法print("B的构造方法")def say(self):# A.say(self) 调用父类的say方法super().say()  # 通过super()调用父类的方法print("say BBB")
b = B()
b.say()'''
A的构造方法
B的构造方法
A:  <__main__.B object at 0x0000000001514748>
say AAA
say BBB
'''

三、多态

1、多态描述

        多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。 

2、多态注意事项

①. 多态是方法的多态,属性没有多态

. 多态的存在有2个必要的条件:继承、方法重写

class Animal:def shout(self):print("动物发出的声音")class Dog(Animal):def shout(self):print("小狗汪汪叫")class Cat(Animal):def shout(self):print("小猫喵喵叫")def animalShout(a):a.shout() #传入的对象不同,shout方法对应的实际行为也不同。animalShout(Dog())
animalShout(Cat())'''
执行结果:
小狗汪汪叫
小猫喵喵叫
'''

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

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

相关文章

洗地机哪个牌子比较好?家用洗地机推荐

洗地机是可以做到扫地的同时把地也拖了&#xff0c;可以做到高效清洁&#xff0c;减轻家务负担。还具有杀菌功能&#xff0c;不用担心拖完地之后地面还有细菌滋生啦&#xff0c;洗地机可以做到即洗即干&#xff0c;无需等待拖完地之后还潮湿不能走路&#xff0c;尤其对于木地板…

2024秋招BAT核心算法 | 详解图论

图论入门与最短路径算法 图的基本概念 由节点和边组成的集合 图的一些概念&#xff1a; ①有向边&#xff08;有向图&#xff09;&#xff0c;无向边&#xff08;无向图&#xff09;&#xff0c;权值 ②节点&#xff08;度&#xff09;&#xff0c;对应无向图&#xff0c;…

统计学 一元线性回归

统计学 一元线性回归 回归&#xff08;Regression&#xff09;&#xff1a;假定因变量与自变量之间有某种关系&#xff0c;并把这种关系用适当的数学模型表达出来&#xff0c;利用该模型根据给定的自变量来预测因变量 线性回归&#xff1a;因变量和自变量之间是线性关系 非线…

CF756div3 vp

又被薄纱了&#xff0c;rk就不放了&#xff0c;好丢人QwQDashboard - Codeforces Round 756 (Div. 3) - CodeforcesA. Make Even小分类讨论题意&#xff1a;给定一个数&#xff0c;每次操作可以选取其前缀然后翻转其前缀&#xff0c;问你最少操作几次可以把该数变为偶数思路&am…

HCIP---回顾HCIA

HCIA回顾&#xff1a; 抽象语言---编码 编码---二进制 二进制---电信号 处理电信号 OSI参考模型----OSI/RM (Open System Interconnect-----开放式系统互连) 应用层&#xff1a;为终端用户提供网络服务接口 表示层&#xff1a;提供数据格式转换服务 会话层&#xff1a…

可视化项目管理,控制项目进度,项目经理需要做好以下工作

对于项目的管理者来说&#xff0c;项目信息透明&#xff0c;能够更容易让管理者发现项目中的问题&#xff0c;及时找到问题的原因和相关任务的责任人。 当项目信息能相对精准地呈现给管理者时&#xff0c;也能促进项目成员也能更加认真负责的完成任务&#xff0c;不会找借口推…

Verilog 学习第八节(数码管段码显示)

共阴极数码管&#xff1a;低电平端接的都是0&#xff0c;高电平端哪里设置为1 &#xff0c;哪里就亮~ 共阳极数码管与之相反~ 视觉暂留&#xff1a; 对于三位的共阴极数码管 第0.01s&#xff1a;让数码管0的a段亮&#xff0c;其他数码管全灭 Sel0为高电平&#xff0c;sel1和sel…

开源鸿蒙南向嵌入学习笔记——NAPI框架学习(一)

开源鸿蒙南向嵌入学习笔记——NAPI框架学习&#xff08;一&#xff09; 前言——系列介绍 本系列文章主要是记录笔者在鸿蒙南向的学习与工作中的知识点笔记记录&#xff0c;其中不止会针对鸿蒙中的学习问题进行思考与记录&#xff0c;也会对涉及到的一些嵌入式等其他领域知识&…

Telink之标准SDK的介绍_1

前提&#xff1a;常见的项目架构&#xff1a;应用层----》驱动层----》硬件层 1、软件组织架构 顶层⽂件夹( 8 个)&#xff1a; algorithm&#xff0c;application&#xff0c;boot&#xff0c;common&#xff0c;drivers&#xff0c;proj_lib&#xff0c;stack&#xff0c;v…

HBase常用Shell命令

HBase提供了一个非常方便的命令行交互工具HBase Shell。通过HBase Shell&#xff0c;HBase可以与MySQL命令行一样创建表、索引&#xff0c;也可以增加、删除和修改数据&#xff0c;同时集群的管理、状态查看等也可以通过HBase Shell实现。 一、数据定义语言 数据定义语言&…

LeetCode 1599. Maximum Profit of Operating a Centennial Wheel【数组,模拟】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

[ 攻防演练演示篇 ] 利用 shiro 反序列化漏洞获取主机权限

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

ATool软件使用实验(22)

实验目的 1、学习ATool软件监控主机行为的原理&#xff1b; 2、学习利用ATool软件监控可疑进程的行为&#xff1b; 3、学习利用ATool软件实现对本机进行文件、注册表管理&#xff1b; 4、学习利用ATool软件实现对本机进行内核模块信息和HOOK信息查看。 预备知识 ATool是针…

测试按方向的分类

按方向分(都是在系统测试阶段测试的) 功能测试&#xff1a;举例说明什么是功能 性能测试 ①压力测试&#xff1a;不断地增加压力&#xff0c;从而找到系统的极限 ②负载测试&#xff1a;系统在极限工作条件下&#xff0c;最多能持续多久——可能发生内存泄漏/溢出&#xff0c;导…

Appium+Python连接真机、跳过登录页、Unexpected error while obtaining UI hierarchy问题

Appium连接真机 使用数据线连接电脑&#xff0c;然后选择文件传输方式 打开手机设置拉至底部&#xff0c;点击关于手机&#xff0c;连续点击7次版本号打开开发者模式 点击设置中的系统与更新&#xff0c;找到开发者选项----> 打开USB调试即可 在终端中输入adb devices确定…

案例解读| 从集中告警平台发展趋势看城商行如何落地数字化转型(二)

上期我们以具体案例入手&#xff0c;分享了集中告警平台到底应该与集中监控平台解耦还是紧绑定等问题。这一期依旧从具体案例切入&#xff0c;跟大家一起探索下告警与服务台的对接过程&#xff0c;以及这个过程中可能产生的问题。上期内容&#xff0c;一键回顾不迷路→案例解读…

angular技术(持续更新)

css类绑定[class.color-blue]"isBlue()" 如果isBlue()返回为true 这里使用color-blue的class样式style样式绑定[style.background-color]"canclick ? blue: red" 组件与模块模块的元数据*declarations: 用于指定属于这个模块的视图类&#xff08;View Cla…

YOLOV5中添加CBAM模块详解——原理+代码

目录一、前言二、CAM1. CAM计算过程2. 代码实现3. 流程图三、SAM1. SAM计算过程2. 代码实现3. 流程图四、YOLOv5中添加CBAM模块参考文章一、前言 由于卷积操作通过融合通道和空间信息来提取特征&#xff08;通过NNNNNN的卷积核与原特征图相乘&#xff0c;融合空间信息&#xff…

代码随想录-51-110.平衡二叉树

目录前言题目1.求高度和深度的区别节点的高度节点的深度2. 本题思路分析&#xff1a;3. 算法实现4. pop函数的算法复杂度5. 算法坑点前言 在本科毕设结束后&#xff0c;我开始刷卡哥的“代码随想录”&#xff0c;每天一节。自己的总结笔记均会放在“算法刷题-代码随想录”该专…

学习笔记:基于SpringBoot的牛客网社区项目实现(二)之Spring MVC入门

1.1 函数的返回值为空&#xff0c;因为可以使用response对象向浏览器返回数据。声明了request对象和response对象&#xff0c;dispatcherservlet自动将这两个对象传入 RequestMapping("/http")public void http(HttpServletRequest request, HttpServletResponse re…