Python入门12:面向对象的三大特征与高级特性详解

面向对象编程(OOP)是Python编程中非常重要的一部分,它通过封装继承多态这三大特征,帮助我们更好地组织和管理代码。除此之外,Python还提供了一些其他特性,如类属性类方法静态方法,进一步增强了面向对象编程的灵活性和功能性。本文将详细介绍这些特性,并通过代码示例帮助你更好地理解。

一、面向对象有三大特征

三种:封装性、继承性、多态性

1、封装

在Python代码中,封装有两层含义:
① 把现实世界中的主体中的 属性和⽅法书写到类的⾥⾯的操作 即为封装。
封装可以为属性和⽅法添加为私有权限,不能直接被外部访问

1.1、封装中的私有属性和私有⽅法

在⾯向对象代码中,我们可以把属性和⽅法分为两⼤类:公有(属性、⽅法)、私有(属性、⽅法)
Python:公有(属性、⽅法),私有(属性、⽅法)
公有属性和公有⽅法:⽆论在类的内部还是在类的外部我们都可以对属性和⽅法进⾏操作。
但是有些情况下,我们不希望在类的外部对类内部的属性和⽅法进⾏操作。我们就可以把这个属性或⽅法封装成私有形式。

1.2、私有属性

设置私有属性和私有⽅法的⽅式⾮常简单:在属性名和⽅法名 前⾯ 加上 两个下划线 __ 即可。设置私有属性后,不能直接在类的外面访问私有属性,但是如果我们在在类外部访问私有属性,那么我们需要再类的内部定义访问的“接口”(函数),专门实现私有属性的访问。 接⼝就是我们通常说的⼀个函数,这个函数可以实现对某些属性的访问(设置与获取)。 在Python中, ⼀般定义函数名' get_xx '⽤来获取私有属性,定义' set_xx '⽤来修改私有属性值。
class Person:def __init__(self, name, age):self.__name = name  # 私有属性self.__age = age  # 私有属性def get_name(self):  # 公共方法,用于访问私有属性return self.__namedef set_name(self, name):  # 公共方法,用于修改私有属性self.__name = namedef get_age(self):return self.__agedef set_age(self, age):if age > 0:self.__age = ageelse:print("年龄不能为负数!")# 使用
person = Person("张三", 20)
print(person.get_name())  # 访问私有属性
person.set_name("李四")  # 修改私有属性
print(person.get_name())

运行结果:

对私有属性间接的进行访问:

class People:def __init__(self, name, age):self.__name = nameself.__age = agedef tell_info(self):print('name:<%s> age:<%s>' % (self.__name, self.__age))def set_info(self, name, age):if not isinstance(name, str):print('名字必须是字符串类型')returnif not isinstance(age, int):print('年龄必须是数字类型')returnself.__name = nameself.__age = age# 创建实例并调用方法
p = People('jack', 38)
p.tell_info()  # 输出:name:<jack> age:<38>p.set_info('jennifer', 18)
p.tell_info()  # 输出:name:<jennifer> age:<18>p.set_info(123, 35)  # 输出:名字必须是字符串类型
p.tell_info()  # 输出:name:<jennifer> age:<18>

运行结果:

1.3、私有方法

class ATM:def __card(self):print('插卡')def __auth(self):print('用户认证')def __input(self):print('输入取款金额')def __print_bill(self):print('打印账单')def __take_money(self):print('取款')# 定义一个对外提供服务的公共方法def withdraw(self):self.__card()self.__auth()self.__input()self.__print_bill()self.__take_money()# 创建实例并调用公共方法
atm = ATM()
atm.withdraw()

运行结果:

 

1.4、封装的意义

  • 数据隐藏:通过将属性设置为私有(使用双下划线__),可以防止外部直接访问和修改对象的内部数据。

  • 接口暴露:通过提供公共方法(如get_xxset_xx),可以控制外部对私有属性的访问和修改。

类中的私有属性和私有⽅法,不能被其⼦类继承。

2、继承

2.1、什么是继承?

继承是面向对象编程的另一个重要特征。它允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用和扩展。

继承几个基本概念:

1、继承:⼀个类从另⼀个已有的类获得其成员的相关特性,就叫作继承!
2、派⽣:从⼀个已有的类产⽣⼀个新的类,称为派⽣!
很显然,继承和派⽣其实就是从不同的⽅向来描述的相同的概念⽽已,本质上是⼀样的!
3、⽗类:也叫作基类,就是指已有被继承的类!
4、⼦类:也叫作派⽣类或扩展类
5、扩展:在⼦类中增加⼀些⾃⼰特有的特性,就叫作扩展,没有扩展,继承也就没有意义了!
6、单继承:⼀个类只能继承⾃⼀个其他的类,不能继承多个类,单继承也是⼤多数⾯向对象语⾔的特性!
7、多继承:⼀个类同时继承了多个⽗类, (C++、Python等语⾔都⽀持多继承)

2.2、继承的基本语法

class B(object):pass
class A(B):pass
a = A()
a.B中的所有公共属性
a.B中的所有公共⽅法

2.3、单继承

单继承是指一个子类只能继承一个父类。通过继承,子类可以复用父类的属性和方法,同时还可以扩展自己的属性和方法。

class Animal:def __init__(self, name):self.name = namedef speak(self):print(f"{self.name} 在叫")class Dog(Animal):  # 继承自Animal类def bark(self):print(f"{self.name} 汪汪汪!")# 实例化Dog对象
dog = Dog("旺财")
dog.speak()  # 调用父类方法
dog.bark()  # 调用子类方法

运行结果:

 

2.4、单继承的传递性

在Python继承中,如A类继承了B类,B类⼜继承了C类。则根据 继承的传递性 ,则A类也会⾃动继承C类中所有属性和⽅法(公共)
class C(object):def func(self):print('我是C类中的相关⽅法func')class B(C):passclass A(B):passa = A()
a.func()

运行结果:

2.5、多继承

Python支持多继承,即一个子类可以同时继承多个父类。虽然多继承允许我们同时继承⾃多个类,但是实际开发中,应尽量避免使⽤多继承,因为如果两个类中出现了相同的属性和⽅法就会产⽣命名冲突。

class you_car(object):y_name = "油车"def use_you(self):print("我是油车,我使用的是汽油驱动!!!")class dian_car(object):d_name = "电车"def use_dian(self):print("我是电车,我使用的是电力驱动")class hunhe_car(you_car,dian_car):yd_name = "油电混动"def use_hunhe(self):print("我是油电混懂,我既能够使用汽油驱动,又能够使用电力驱动")hh = hunhe_car()
hh.use_hunhe()
hh.use_you()
hh.use_dian()
print(hh.y_name)
print(hh.d_name)
print(hh.yd_name)

运行结果:

2.6、⼦类扩展:重写⽗类属性和⽅法
扩展特性:继承让⼦类继承⽗类的所有公共属性和⽅法,但是如果仅仅是为了继承公共属性和⽅法,继承就没有实际的意义了,应该是在继承以后,⼦类应该有⼀些⾃⼰的属性和⽅法。
什么是重写?
如果⼦类中的属性和⽅法与⽗类中的属性或⽅法同名 则⼦类中的属性或⽅法会对⽗类中同名的属性或⽅法进⾏覆盖(重写)

 

# 重写2:类⽅法的调⽤顺序,当我们在⼦类中重构⽗类的⽅法后,Cat⼦类的实例先会在⾃⼰的类 Cat 中查找该⽅法,
# 当找不到该⽅法时才会去⽗类 Animal 中查找对应的⽅法。
class Animal():def call(self):print("我是动物类中叫方法")class Cat(Animal):# 自定义def cat_call(self):print("我是猫类中喵喵叫的方法")# 重写方法def call(self):print("我是猫类中喵喵叫的方法")
# 父类中的方法功能不够,在子类中的解决方法:
# 1、重写
# 2、定义一个新的方法
c = Cat()
c.call()

运行结果:

 

2.7、super()调⽤⽗类属性和⽅法

在子类中,可以通过super()函数调用父类的方法,尤其是在重写父类方法时,仍然希望保留父类的行为。在Python3以 后版本中,调⽤⽗类的属性和⽅法我们只需要使⽤ super().属性 或 super().⽅法名() 就可以完 成调⽤了。

class Car:def __init__(self, brand, model):self.brand = brand   # 品牌self.model = model  # 型号def run(self):print(f"{self.brand} {self.model} 在行驶!")class ElectricCar(Car):# 重写构造函数def __init__(self, brand, model, battery):super().__init__(brand, model)  # 调用父类的构造方法self.battery = battery# 重写run方法def run(self):super().run()  # 调用父类的run方法print(f"在以 {self.battery} 千米每小时的速度在行驶")tesla = ElectricCar("Tesla", "Model S", 75)
tesla.run()

运行结果:

 

2.8.MRO属性或MRO⽅法:⽅法解析顺序

当多个父类中有同名方法时,Python 需要确定调用哪个父类的方法,这就涉及到方法解析顺序(MRO)。Python 使用 C3 线性化算法来计算 MRO。可以使用__mro__属性或mro()方法查看类的 MRO。

class A:def method(self):print("Method from A")class B(A):def method(self):print("Method from B")class C(A):def method(self):print("Method from C")class D(B, C):pass# 查看D类的MRO
print(D.__mro__)# 创建D类的实例
d = D()
# 调用method方法
d.method()

运行结果:

 

class Parent1:def __init__(self):print("Parent1 __init__")class Parent2:def __init__(self):print("Parent2 __init__")class Child(Parent1, Parent2):def __init__(self):# 调用父类的__init__方法super().__init__()print("Child __init__")# 创建Child类的实例
child = Child()
print(Child.__mro__)

 运行结果:

 

说明:有MRO⽅法解析顺序可知,在类的继承中,当某个类创建了⼀个对象时,调⽤属性或⽅法, ⾸先 在⾃身类中去寻找,如找到,则直接使⽤,停⽌后续的查找。如果未找到,继续向上⼀级继承的类中去 寻找,如找到,则直接使⽤,没有找到则继续向上寻找...直到object类,这就是Python类继承中,其⽅法解析顺序。

3、多态

3.1、什么是多态?

多态指的是⼀类事物有多种形态。
定义:多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以产⽣ 不同的执⾏结果。
① 多态依赖继承(不是必须的)
② ⼦类⽅法必须要重写⽗类⽅法。
好处:调⽤灵活,有了多态,更容易编写出通⽤的代码,做出通⽤的编程,以适应需求的不断变化!

3.2多态原理图

3.3、多态代码的实现

# ⽗类Fruit
class Fruit(object):def makejuice(self):print('i can make juice')# ⼦类:苹果
class Apple(Fruit):# 重写⽗类⽅法def makejuice(self):print('i can make apple juice')# ⼦类:⾹蕉
class Banana(Fruit):# 重写⽗类⽅法def makejuice(self):print('i can make banana juice')# ⼦类:橘⼦
class Orange(Fruit):# 重写⽗类⽅法def makejuice(self):print('i can make orange juice')# 定义⼀个公共接⼝(专⻔⽤于实现榨汁操作)
def service(obj):# obj要求是⼀个实例化对象,可以传⼊苹果对象/⾹蕉对象obj.makejuice()# 调⽤公共⽅法
service(Orange())

运行结果:

3.4、在Python中还有哪些多态的案例呢?

# 数值相加
print(1 + 2)  # 输出:3# 字符串拼接
print("Hello" + " World")  # 输出:Hello World# 列表合并
print([1, 2] + [3, 4])  # 输出:[1, 2, 3, 4]

二、面向对象的其他高级特性

1、类属性

类属性是属于类本身的属性,而不是类的实例。类属性被该类的所有实例对象所共享。

class Person(object):# 定义类属性count,⽤于记录⽣成的Person类对象的个数count = 0# 定义⼀个__init__魔术⽅法,⽤于进⾏初始化操作def __init__(self, name):self.name = name# 对count类属性进⾏+1操作,⽤于记录这个Person类⼀共⽣成了多少个对象Person.count += 1# 1、实例化对象p1
p1 = Person('Tom')
p2 = Person('Harry')
p3 = Person('Jennifer')# 2、在类外部输出类属性
print(f'我们共使⽤Person类⽣成了{Person.count}个实例对象')

运行结果:

2、类方法

为什么需要类⽅法,在⾯向对象中,特别强调数据封装性。所以不建议直接在类的外部对 类属性 进⾏直接获取。所以我们如果想操作类属性,建议使⽤类⽅法。
class Tool(object):# 定义⼀个类属性countcount = 0# 定义⼀个__init__初始化⽅法def __init__(self, name):self.name = nameTool.count += 1# 封装⼀个类⽅法:专⻔实现对Tool.count类属性进⾏操作@classmethod  # 声明为类⽅法,⽤于对类属性进⾏操作def get_count(cls):  # cls代表类对象print(f'我们使⽤Tool类共实例化了{cls.count}个⼯具')t1 = Tool('斧头')
t2 = Tool('榔头')
t3 = Tool('铁锹')Tool.get_count()

运行结果:

3、静态方法

静态方法既不操作实例属性,也不操作类属性。它通常用于实现与类相关的工具函数。

class Game:@staticmethoddef menu():print("1. 开始游戏")print("2. 游戏暂停")print("3. 退出游戏")# 调用静态方法
Game.menu()

三、总结

面向对象编程的三大特征——封装继承多态,是Python编程中非常重要的概念。通过封装,我们可以隐藏对象的内部实现细节;通过继承,我们可以复用和扩展代码;通过多态,我们可以编写更加通用和灵活的代码。此外,Python还提供了类属性类方法静态方法等高级特性,进一步增强了面向对象编程的功能性。

希望本文能帮助你更好地理解Python面向对象编程的核心概念,并在实际开发中灵活运用这些特性!

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

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

相关文章

对计算机中缓存的理解和使用Redis作为缓存

使用Redis作为缓存缓存例子缓存的引入 Redis缓存的实现 使用Redis作为缓存 缓存 ​什么是缓存&#xff0c;第一次接触这个东西是在考研学习408的时候&#xff0c;计算机组成原理里面学习到Cache缓存&#xff0c;用于降低由于内存和CPU的速度的差异带来的延迟。它是在CPU和内存…

音视频入门基础:RTP专题(12)——RTP中的NAL Unit Type简介

一、引言 RTP封装H.264时&#xff0c;RTP对NALU Header的nal_unit_type附加了扩展含义。 由《音视频入门基础&#xff1a;H.264专题&#xff08;4&#xff09;——NALU Header&#xff1a;forbidden_zero_bit、nal_ref_idc、nal_unit_type简介》可以知道&#xff0c;nal_unit…

Linux 驱动入门(6)—— IRDA(红外遥控模块)驱动

文章目录 一、编译替换内核和设备树二、IRDA&#xff08;红外遥控模块&#xff09;1. 红外遥控简介2. 红外遥控器协议3. 编程思路 三、驱动代码1. GPIO 实现1.1 驱动层代码1.2 应用层代码 2. 设备树实现2.1 修改设备树2.2 驱动层代码2.3 应用层代码 3. 上机测试 一、编译替换内…

QSNCTF-WEB做题记录(2)

[第一章 web入门]常见的搜集 来自 <天狩CTF竞赛平台> 1&#xff0c;首先就是对网站进行目录枚举爆破 dirsearch -u http://challenge.qsnctf.com:31616 -x 404,403 得到如下的目录&#xff0c;分别查看一下内容 /.DS_Store /inde…

「软件设计模式」责任链模式(Chain of Responsibility)

深入解析责任链模式&#xff1a;用C打造灵活的请求处理链 引言&#xff1a;当审批流程遇上设计模式 在软件系统中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个请求需要经过多个处理节点的判断&#xff0c;每个节点都有权决定是否处理或传递请求。就像企业的请假审批…

Ocelot 请求聚合

请求聚合 当下游服务是返回404状态码&#xff0c;在返回结果中&#xff0c;其对应的值则为空值&#xff0c; 即使聚合路由中所有的下游服务都返回404状态码&#xff0c;聚合路由的返回结果也不会是404状态码。 Ocelot允许你声明聚合路由&#xff0c;这样你可以把多个正常的Ro…

MongoDB安装与配置 导入导出

1、MongoDB的安装 首先cd到目录 cd /usr/local/ 执行下载 wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-7.0.7.tgz 解压文件 tar -xvf mongodb-linux-x86_64-rhel80-7.0.7.tgz 将解压后的“mongodb-linux-x86_64-rhel80-7.0.7”文件夹重命名…

Kotlin 知识点二 延迟初始化和密封类

对变量延迟初始化 Kotlin 语言的许多特性&#xff0c;包括变量不可变&#xff0c;变量不可为空&#xff0c;等等。这些特性 都是为了尽可能地保证程序安全而设计的&#xff0c;但是有些时候这些特性也会在编码时给我们带来不 少的麻烦。 比如&#xff0c;如果你的类中存在很多…

简单介绍 SSL 证书类型: DV、OV、EV 的区别

SSL证书类型DV、OV、EV 区别&#xff1a; DV(域名验证型)SSL证书 OV(组织验证型)SSL证书 EV(扩展验证型)SSL证书

深度解析SmartGBD助力Android音视频数据接入GB28181平台

在当今数字化时代&#xff0c;视频监控与音视频通信技术在各行各业的应用愈发广泛。GB28181协议作为中国国家标准&#xff0c;为视频监控设备的互联互通提供了规范&#xff0c;但在实际应用中&#xff0c;许多Android终端设备并不具备国标音视频能力&#xff0c;这限制了其在相…

1分钟用DeepSeek编写一个PDF转Word软件

一、引言 如今&#xff0c;在线工具的普及让PDF转Word成为了一个常见需求&#xff0c;常见的pdf转word工具有收费的wps&#xff0c;免费的有pdfgear&#xff0c;见下文&#xff1a; PDFgear:一款免费的PDF编辑、格式转化软件-CSDN博客 还有网上在线的免费pdf转word工具smallp…

PyCharm Professional 2025 安装配置全流程指南(Windows平台)

一、软件定位与核心功能 PyCharm 2025 是 JetBrains 推出的智能 Python IDE&#xff0c;新增深度学习框架自动补全、实时性能热力图等功能1。相较于社区版&#xff0c;专业版支持&#xff1a; Web开发&#xff08;Django/Flask&#xff09;数据库工具&#xff08;PostgreSQL/…

DeepSeek回答:AI时代Go语言学习路线

最近有小伙伴经常会问&#xff1a;**该如何学习入门Go语言&#xff1f;怎样提升Go语言Coding水平&#xff1f;**这篇文章我们就使用DeepSeek来梳理下Go语言在AI时代的学习路线。 向DeepSeek提问的问题原文&#xff1a; 你现在是一名资深的Go语言工程师&#xff0c;精通Go语言并…

OpenGL ES -> GLSurfaceView绘制点、线、三角形、正方形、圆(顶点法绘制)

XML文件 <?xml version"1.0" encoding"utf-8"?> <com.example.myapplication.MyGLSurfaceViewxmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"…

嵌入式项目:STM32刷卡指纹智能门禁系统

本文详细介绍基于STM32的刷卡指纹智能门禁系统。 获取资料/指导答疑/技术交流/选题/帮助&#xff0c;请点链接&#xff1a; https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt 1 系统功能 1.1 功能概述 本系统由STM32硬件端&#xff08;下位机&#xff09;…

Dubbo RPC 原理

一、Dubbo 简介 Apache Dubbo 是一款高性能、轻量级的开源 RPC 框架&#xff0c;支持服务治理、协议扩展、负载均衡、容错机制等核心功能&#xff0c;广泛应用于微服务架构。其核心目标是解决分布式服务之间的高效通信与服务治理问题。 二、Dubbo 架构设计 1. 核心组件 Prov…

RBAC授权

4 RBAC授权 4.1 什么是RBAC 在Kubernetes中&#xff0c;所有资源对象都是通过API进行操作&#xff0c;他们保存在etcd里。而对etcd的操作我们需要通过访问kube-apiserver来实现&#xff0c;上面的Service Account其实就是APIServer的认证过程&#xff0c;而授权的机制是通过RBA…

C/C++ | 每日一练 (4)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (4)题目参考答案基础容器序列容器std:…

HarmonyOS 5.0应用开发——鸿蒙接入高德地图实现POI搜索

【高心星出品】 文章目录 鸿蒙接入高德地图实现POI搜索运行结果&#xff1a;准备地图编写ArkUI布局来加载HTML地图 鸿蒙接入高德地图实现POI搜索 在当今数字化时代&#xff0c;地图应用已成为移动设备中不可或缺的一部分。随着鸿蒙系统的日益普及&#xff0c;如何在鸿蒙应用中…

Linux系统:服务器常见服务默认IP端口合集

服务器的默认IP端口取决于所使用的协议和服务类型。以下是一些常见服务和协议的默认端口&#xff1a; 服务端口实例&#xff1a; HTTP服务 默认端口&#xff1a;80 说明&#xff1a;用于普通的HTTP网页访问。例如&#xff0c;访问 http://example.com 时&#xff0c;默认使用8…