面向对象三大特征(python)

 

目录

1. 封装

为什么使用封装?

如何实现封装?

一个简单的封装示例

 二.继承

为什么使用继承?

如何实现继承?

一个简单的继承示例

使用继承的好处

三.多态

为什么使用多态?

如何实现多态?

一个简单的多态示例

使用多态的好处


  1. 封装:封装是指将数据和操作数据的方法捆绑在一起,通过这种方式可以控制数据的访问权限,使得对象的内部细节对外部不可见,从而提高了代码的安全性和可靠性。

  2. 继承:继承是指一个类可以基于另一个类来创建新类的机制。子类可以继承父类的属性和方法,并且可以在不改变父类的情况下扩展或修改功能,从而实现代码的重用和扩展。

  3. 多态:多态是指同一种操作作用于不同的对象时,可以产生不同的行为。通过多态,可以编写通用的代码,让程序在运行时根据对象的实际类型来决定调用哪个方法,提高了代码的灵活性和可扩展性。

1. 封装

封装:面向对象编程的核心原则

在面向对象编程中,封装是一种核心原则,它允许我们将数据和操作封装在一个单独的单元中,从而隐藏了数据的具体实现细节,只暴露出必要的接口供外部使用。这种方式提高了代码的可维护性、可重用性和安全性

为什么使用封装?

封装的主要目的是将数据和操作打包在一起,形成一个独立的单元,外部只能通过指定的接口来访问数据和操作,而不能直接访问内部实现细节。这样做的好处有:

  1. 隐藏实现细节:封装可以隐藏数据的具体实现细节,使得外部无法直接访问和修改数据,从而提高了代码的安全性和可维护性。

  2. 简化接口:封装可以将复杂的实现细节封装在内部,只暴露出简单的接口供外部使用,使得代码更易于理解和使用。

  3. 提高重用性:封装可以将通用的功能封装在一个单元中,使得这些功能可以在不同的地方重复使用,提高了代码的重用性。

如何实现封装?

在面向对象编程中,封装通常通过类和对象来实现。类将数据和操作封装在一起,而对象则是类的实例,可以通过对象来访问封装在类中的数据和操作。

在Python中,我们可以使用访问控制符(如私有成员变量和方法)来实现封装。通过将属性或方法命名以双下划线开头,我们可以将它们设置为私有的外部无法直接访问,只能通过类提供的接口来访问。

一个简单的封装示例

让我们通过一个简单的例子来说明封装的概念。假设我们有一个 Person 类,表示一个人,其中包含姓名和年龄两个属性,我们希望将年龄设置为私有的,只能通过提供的接口来访问。

class BankAccount:def __init__(self, account_number, balance=0):self.account_number = account_numberself.__balance = balance  # 封装的私有属性def deposit(self, amount):if amount > 0:self.__balance += amountprint(f"Deposit of {amount} successful.")else:print("Invalid deposit amount.")def withdraw(self, amount):if 0 < amount <= self.__balance:self.__balance -= amountprint(f"Withdrawal of {amount} successful.")else:print("Invalid withdrawal amount.")def get_balance(self):return self.__balance# 创建银行账户对象
acc1 = BankAccount("12345678", 1000)# 尝试直接访问私有属性
# print(acc1.__balance)  # 无法直接访问私有属性# 通过公有方法访问私有属性
print("Current balance:", acc1.get_balance())# 进行存款和取款操作
acc1.deposit(500)
print("Current balance after deposit:", acc1.get_balance())acc1.withdraw(200)
print("Current balance after withdrawal:", acc1.get_balance())

这个示例中,BankAccount 类封装了账户号码和账户余额,其中 __balance 是私有属性,通过 deposit() 和 withdraw() 方法实现对账户余额的操作,同时通过 get_balance() 方法来获取账户余额。

 二.继承

为什么使用继承?

继承允许我们建立一个层次结构,通过在父类中定义通用的属性和方法,然后在子类中添加特定的功能或行为,从而实现代码的重用和扩展。这种方法使得代码更加模块化,易于理解和维护。

如何实现继承?

在Python中,实现继承非常简单。我们可以通过在子类的定义中将父类作为参数传递给子类来实现继承。子类继承了父类的所有属性和方法,并可以添加新的属性和方法或覆盖父类的方法。

一个简单的继承示例

# 父类
class Animal:def __init__(self, name):self.name = namedef speak(self):return f"{self.name} 叫!"# 子类继承父类
class Dog(Animal):def Dog_speak(self):return super().speak()class Cat(Animal):def Dog_speak(self):return super().speak()# 创建对象并调用方法
dog = Dog("狗")
print(dog.speak())cat = Cat("猫")
print(cat.speak())

使用继承的好处

通过继承,我们可以避免重复编写相似的代码,提高了代码的复用性。当我们需要添加新的功能或行为时,只需要在子类中进行修改,而不需要修改父类,这样可以减少代码的维护成本。

继承还使得代码更具灵活性和可扩展性,我们可以轻松地添加新的子类来扩展现有的功能,而不会影响到其他部分的代码。

三.多态

多态:面向对象编程的灵活性之道

在面向对象编程中,多态是一种重要的概念,它允许我们使用统一的接口来操作不同类型的对象,从而实现灵活性和可扩展性。多态使得代码更加通用、易于理解和维护。

为什么使用多态?

多态的主要目的是提高代码的灵活性和可扩展性。通过多态,我们可以编写与具体类型无关的代码,从而使得代码更加通用和可重用。当我们需要添加新的类型时,只需要编写新的类并实现相同的接口,而不需要修改现有的代码,这样大大提高了代码的可维护性和可扩展性。

如何实现多态?

在面向对象编程中,多态通常通过继承和方法重写来实现。当子类继承自父类,并重写了父类的方法时,我们可以使用父类的引用来引用子类的对象,并调用相同的方法,实现了多态。

另一种实现多态的方式是通过接口。在一些编程语言中,如Java,我们可以定义一个接口,并要求所有实现该接口的类都实现相同的方法。然后我们可以使用接口的引用来引用实现了该接口的不同类的对象,并调用相同的方法,实现了多态。

一个简单的多态示例

让我们通过一个简单的例子来说明多态的概念。假设我们有一个 Shape 类,表示形状,其中包含一个 draw() 方法用来绘制形状。然后我们创建了两个子类 Circle 和 Rectangle,分别表示圆和矩形,并重写了 draw() 方法。

class Shape:def draw(self):passclass Circle(Shape):def draw(self):print("绘制圆形")class Rectangle(Shape):def draw(self):print("绘制矩形")

现在,我们可以使用多态来调用不同子类的 draw() 方法,而不需要知道具体是哪个子类。

def draw_shape(shape):shape.draw()circle = Circle()
rectangle = Rectangle()draw_shape(circle)     # 输出:绘制圆形
draw_shape(rectangle)  # 输出:绘制矩形

在这个例子中,draw_shape() 函数接受一个 Shape 类型的参数,然后调用该参数的 draw() 方法。由于 Circle 和 Rectangle 类都继承自 Shape 类,并重写了 draw() 方法,因此我们可以传递 Circle 和 Rectangle 类的对象作为参数,实现了多态。

使用多态的好处

多态使得代码更加灵活、通用和易于扩展。通过统一的接口操作不同类型的对象,我们可以编写与具体类型无关的代码,提高了代码的可重用性和可维护性。当我们需要添加新的类型时,只需要实现相同的接口,而不需要修改现有的代码,这样大大降低了代码的维护成本

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

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

相关文章

【基于YOLOv8的森林烟雾火焰检测 附源码 数据集】

基于YOLOv8的森林烟雾火焰检测 附源码 数据集 在森林火灾的早期预防和控制中&#xff0c;森林烟雾火焰检测技术发挥着至关重要的作用。本技术通过先进的传感器和图像识别系统&#xff0c;实时监测森林区域中的烟雾和火焰异常&#xff0c;快速响应可能的火灾发生。森林烟雾火焰…

go 基础概念-变量和类型使用注意事项

在 Goland 语言中&#xff0c;变量是存储数据的容器&#xff0c;而类型定义了变量可以存储的数据种类和可以对变量执行的操作。以下是在使用 Go 变量和类型时的一些注意事项&#xff1a; 变量声明 显式声明&#xff1a;使用 var 关键字显式声明变量类型。类型推断&#xff1a…

R-tree:一种高效的空间数据索引结构

引言&#xff1a; 在处理大规模空间数据集&#xff0c;如地理信息系统&#xff08;GIS&#xff09;中的遥感数据时&#xff0c;高效的数据存储和查询至关重要。R-tree&#xff0c;作为一种自平衡的空间数据索引结构&#xff0c;因其出色的性能而在空间数据库中得到了广泛应用。…

理解C语言中的位操作和整数类型:一个温度传感器读取问题的解析

前言:当我们编写嵌入式系统的代码时&#xff0c;我们经常需要使用位操作来处理硬件设备的数据。然而&#xff0c;如果我们对C语言的位操作和整数类型不完全理解&#xff0c;可能会遇到一些难以理解的问题。在这篇博客中&#xff0c;我将通过一个实际的例子来解释这些概念&#…

git之常见的license及其适用场景

Git之常用license MIT License 特点 MIT 许可证是一种非常宽松的许可证&#xff0c;允许在几乎所有项目中自由使用、修改和分发源代码或二进制形式。它几乎没有使用限制和责任限制。 适用场景 MIT 许可证非常适合开源项目&#xff0c;尤其是那些希望被广泛使用和采纳的项目…

在ubuntu上搭建nexus私有仓库(指定版本以及jdk!)

前言 本来以为搭建一个nexus随随便便就好了&#xff0c;但是遇到了最新版本根本没办法在jdk17下面正常运行—起码我调了一下不知道怎么运行&#xff0c;我才知道。。。不升级版本其实是很有道理的。 这一篇是最新版本的尝试&#xff1a; 在ubuntu上搭建nexus私有仓库[失败草稿…

升级 jQuery:努力打造健康的 Web 生态

jQuery 对 Web 的影响始终是显而易见的。当 jQuery 在 2006 年首次推出时&#xff0c;几乎立即成为 Web 开发人员的基本工具。它简化了 JavaScript 编程&#xff0c;使操作 HTML 文档、处理事件、执行动画等变得更加容易。从那时起&#xff0c;它在 Web 标准和浏览器功能的演变…

从0开始用C写贪吃蛇(基于链表)

目录 1. 游戏背景 2. 游戏效果演示​编辑​编辑​编辑 3. 实现目标 4. 技术要点 5. 控制台程序 5.1 设置控制台窗口的长宽和名字 5.2 控制台屏幕上的坐标COORD 6.Win32 API 6.1 GetStdHandle 6.2 GetConsoleCursorInfo 6.3 CONSOLE_CURSOR_INFO 6.4 SetConsole…

Docker 网络与资源控制

一 Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根 据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默 认网关。因为在同…

带头循环双向链表专题

1. 双向链表的结构 带头链表⾥的头节点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位节点不存储任何有效元素&#xff0c;只是站在这⾥“放哨 的” “哨兵位”存在的意义&#xff1a; 遍历循环链表避免死循环。 2. 双向链表的实现 2.1双向链表结构 typedef int DataTyp…

最新AI创作系统ChatGPT网站源码Midjourney-AI绘画系统,Suno-v3-AI音乐生成大模型。

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

Java-校验规则Integer使用 @NotEmpty注解报错

ApiModelProperty(value "小组id")NotEmpty(message "小组id 不能为空")private Integer teamId; 1.假如不小心Integer使用NotEmpty注解报错 提示&#xff1a; No validator could be found for constraint javax.validation.constraints.NotEmpty va…

Ubuntu终端自动补全

文章目录 前言配置安装zsh安装 oh-my-zsh安装自动补全插件zsh-autosuggestions 参考 前言 Oh My Zsh 是一个针对命令行 shell 的开源框架&#xff0c;主要用于增强和美化命令行环境。它建立在 Zsh&#xff08;一种强大的 shell 替代品&#xff09;之上&#xff0c;提供了丰富的…

Kubernetes Kubelet 的 Cgroups 资源限制机制分析

前言 容器技术的两大技术基石&#xff0c;想必大家都有所了解&#xff0c;即 namespace 和 cgroups。但你知道 cgroups 是如何在 kubernetes 中发挥作用的吗&#xff1f;kubelet 都设置了哪些 cgroups 参数来实现对容器的资源限制的呢&#xff1f;本文就来扒一扒 Kubernetes k…

深度学习框架比较:TensorFlow vs PyTorch

TensorFlow和PyTorch是目前最流行的两个深度学习框架。它们都提供了强大的功能和灵活性&#xff0c;用于构建和训练复杂的深度学习模型。但是&#xff0c;它们在设计理念、用户体验和特定用例支持方面存在一些差异。以下是TensorFlow和PyTorch之间的比较&#xff0c;涵盖了它们…

使用队列对二叉树进行广度遍历

我们要对二叉树进行广度遍历&#xff0c;经典的数据结构就是队列&#xff0c;这也是许多算法题中要用到的基础&#xff0c;下面是一些基本思想 我们首先创建一个队列&#xff0c;开始遍历二叉树&#xff0c;这里记录一个值len&#xff0c;表示当前层有多少个元素&#xff0c;当…

Qt | 键盘事件

Qt | 鼠标事件第四节十、键盘事件 1、Qt 使用 QKeyEvent 类来描述与键盘有关的信息,比如按下或释放键的代码,使用枚举类型 QEvent::Type 描述与键盘有关的事件,比如 QEvent::KeyPress 表示键盘按下事件, QEvent::KeyRelease表示键盘释放事件等。 2、是否接收键盘事件,最…

STC8H8K64U I2C主机模式相关寄存器

STC8H8K64U I2C主机模式相关寄存器 STC8H8K64U-TSSOP20 I2CCFG I2C配置寄存器 I2CMSCR I2C主机控制寄存器 I2CMSST I2C主机状态寄存器 I2CMSAUX I2C主机辅助控制寄存器 I2CTXD I2C数据发送寄存器 I2CRXD I2C数据接收寄存器 I2CCFG I2C配置寄存器 B7ENI2C ENI2C&#xff1a…

文件多进程、多线程访问

处理多进程和多线程的文件读写操作需要确保对共享资源的访问是同步的&#xff0c;以防止数据竞争和不一致性。以下是一些常用的策略和工具&#xff1a; 多线程同步&#xff1a; 内置锁 (synchronized 关键字)&#xff1a;使用 Java 的 synchronized 关键字对代码块或方法进行同…

Android Compose页面跳转Demo

1.引入依赖 //jetpack compose导航 implementation("androidx.navigation:navigation-compose:2.5.3") 2.代码 import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundat…