14_Python面向对象

在这里插入图片描述

面向过程与面向对象

在编程范式(programming paradigms)中,面向过程(Procedural Programming)和面向对象(Object-Oriented Programming,简称OOP)是两种主要的编程风格。

Python是一种多范式编程语言,它支持面向过程编程,也支持面向对象编程。

面向过程编程(Procedural Programming)

  • 重点:面向过程编程主要关注的是过程,即完成任务的步骤。
  • 结构:程序通常由一系列按照顺序执行的函数或语句组成。
  • 数据:数据和逻辑(函数)是分离的。数据通常以全局变量的形式存在,可以被程序中的任何函数访问和修改。
  • 复用:通过函数来复用代码。
  • 例子:C语言是一种典型的面向过程的编程语言。

Python中的面向过程编程示例:

# alculate_area 的函数,它接受两个参数 length 和 width。
'''这个函数的作用是计算一个矩形的面积,计算方式是将长度和宽度相乘,并返回计算结果。- length 和 width 是函数的参数,它们分别代表矩形的长度和宽度。- return 语句用于返回计算得到的面积。
'''
def calculate_area(length, width):return length * width# 定义名为 print_area 的函数,它接受两个参数 length 和 width。
'''这个函数的作用是调用 calculate_area 函数来计算矩形的面积,并打印出面积。
'''
def print_area(length, width):# calculate_area函数调用,将 length 和 width 作为参数传递给 calculate_area 函数area = calculate_area(length, width)# 使用 print 函数输出字符串 “Area:” 和计算得到的面积。print("Area:", area)length = 10
width = 5
# 调用 print_area 函数,并将的 length 和 width 变量作为参数传递给它。
print_area(length, width)
# 结果:Area: 50

面向对象编程(Object-Oriented Programming)

  • 重点:面向对象编程主要关注的是对象,即数据和行为的封装。
  • 结构:程序由类(class)和对象(object)组成。类是对象的蓝图,对象是类的实例。
    • :是一个抽象的模板或蓝图,它定义了一组属性(数据)和方法(函数)。类本身并不代表一个具体的实体,而是描述了属于该类的所有对象共有的特征和行为。
    • 对象:是根据类创建的实体。每个对象都是类的一个实例,它拥有类定义的属性和方法的具体值。你可以将对象视为蓝图的具体实现或建筑物。
  • 数据:数据和操作数据的方法(函数)被封装在一起,称为类的属性和方法。
  • 复用:通过继承和多态来复用代码。
  • 例子:Java和C++是典型的面向对象编程语言。

Python中的面向对象编程示例:

定义一个名为 Rectangle 的类

这里定义了一个名为 Rectangle 的类。类是面向对象编程中的一个核心概念,它为创建对象提供了一个模板。

构造函数 init

__init__ 方法是类的构造函数,它在创建类的实例时自动被调用。这个方法的主要目的是初始化新创建的对象的状态。

  • self 参数是对当前对象的引用,它允许我们在方法内部访问和修改对象的属性。
  • length 和 width 是传递给构造函数的参数,它们定义了矩形的长度和宽度。
  • self.length = length 和 self.width = width 将传入的参数值赋给对象的属性。这些属性是对象状态的组成部分。
方法 calculate_area

calculate_area 是一个实例方法,它定义了 Rectangle 类对象的行为。这个方法计算并返回矩形的面积。

  • self 参数是必须的,因为它指向调用该方法的对象实例。
  • 方法计算面积的方式是将对象的 length 属性与 width 属性相乘。
方法 print_area

print_area 是另一个实例方法,它调用 calculate_area 方法来获取矩形的面积,并将其打印出来。

  • 同样,self 参数指向调用该方法的对象实例。
  • 方法首先调用 calculate_area 方法获取面积,然后使用 print 函数输出面积。
# 定义一个名为 Rectangle 的类,
class Rectangle:# 构造函数 __init__def __init__(self, length, width):self.length = lengthself.width = widthdef calculate_area(self):return self.length * self.widthdef print_area(self):area = self.calculate_area()print("Area:", area)# 创建对象
# -Rectangle(10, 5) 调用 Rectangle 类的构造函数,并传递了长度为 10 和宽度为 5 的参数。
# -rect 是新创建的对象的引用名称。
rect = Rectangle(10, 5)
# 通过 rect 对象调用 print_area 方法。计算并打印出矩形的面积。
rect.print_area()

这段代码演示了面向对象编程的几个关键概念:

  • 封装:数据和操作数据的方法被封装在 Rectangle 类中。
  • 抽象:用户不需要知道 calculate_area 或 print_area 方法的具体实现细节,只需要知道如何使用它们。
  • 实例化:通过类创建具体的对象 rect。
  • 方法调用:通过对象调用方法来执行操作。

面向过程与面向对象对比

  • 数据封装:面向对象编程通过类和对象提供更好的数据封装,而面向过程编程中数据和逻辑通常是分开的。
  • 代码复用:面向对象编程通过继承和多态提供更高级的代码复用机制,而面向过程编程主要依赖于函数。
  • 维护和扩展:面向对象编程更容易维护和扩展,因为它将功能划分为独立的、可重用的对象。
  • 复杂性:面向对象编程可能引入更多的概念(如类、对象、继承、多态等),这可能使程序更复杂,但同时也更灵活。

Python的设计哲学是“优雅”、“明确”和“简单”,它允许程序员根据具体问题选择最适合的编程范式。在Python中,即使使用了面向对象的特性,也可以保持代码的简洁性。

私有属性和私有方法

在面向对象编程中,私有属性和私有方法(有时称为私有防范)是用于实现封装的机制。封装是面向对象编程的四大基本原则之一,它指的是将对象的实现细节隐藏起来,只暴露出有限的接口供外部使用。这样做的好处包括:

  • 保护对象的状态不被外部直接修改,从而保持对象的完整性。
  • 允许在不影响外部代码的情况下更改内部实现。
  • 避免外部代码对内部工作原理的依赖,提高代码的可维护性和可重用性。

在Python中实现私有属性和方法的几种方式:

1. 单下划线前缀 _

在Python中,单下划线前缀是约定俗成的表示,表示属性或方法是受保护的。它告诉外部代码:“这是私有的,不要直接访问或修改”。

尽管这种做法并不强制,但它是一种编程约定,告诉其他开发者这些属性和方法是用于内部使用的。

2. 双下划线前缀 __

在Python中,双下划线前缀会触发名称修饰(name mangling),这是一种防止属性或方法被外部访问的机制。它通过在属性或方法名前加上类名和额外的下划线来“隐藏”它们。

私有防范的意义

私有防范确保了类的内部状态的安全性,并且提供了以下保护措施:

  • 防止意外修改:外部代码不能直接修改私有属性,减少了因意外修改导致的错误。
  • 控制访问:只能通过类的公共接口来访问和修改对象的状态,这允许类在内部实施复杂的逻辑和安全检查。
  • 隐藏实现细节:类的内部实现细节对外部代码是隐藏的,这意味着可以在不影响外部代码的情况下更改内部实现。

通过使用私有属性和方法,可以更好地控制类的行为,并确保其状态的正确性和一致性。

下面是修改后的 Rectangle 类,加入了两个私有属性和一个私有方法。

class Rectangle:# 构造函数 __init__def __init__(self, length, width):# 公有属性self.length = lengthself.width = width# 私有属性,表示矩形是否是正方形self.__is_square = length == width# 私有属性,存储计算过的面积,避免重复计算self.__area = None# 公有方法,计算面积def calculate_area(self):# 如果私有属性 __area 已经有值,直接返回if self.__area is not None:return self.__area# 计算面积并赋值给私有属性 __areaself.__area = self.length * self.widthreturn self.__area# 公有方法,打印面积def print_area(self):area = self.calculate_area()print("Area:", area)# 私有方法,检查矩形是否是正方形def __check_square(self):# 更新私有属性 __is_square 的值self.__is_square = self.length == self.widthreturn self.__is_square# 公有方法,提供外部检查是否是正方形的接口def is_square(self):# 调用私有方法 __check_square 来检查return self.__check_square()# 创建对象
rect = Rectangle(10, 5)
# 通过 rect 对象调用 print_area 方法。计算并打印出矩形的面积。
rect.print_area()# 尝试检查 rect 是否是正方形
print("Is square:", rect.is_square())  # 应该返回 False,因为长度和宽度不相等# 创建一个正方形对象
square = Rectangle(5, 5)
# 通过 square 对象调用 print_area 方法。计算并打印出正方形的面积。
square.print_area()# 尝试检查 square 是否是正方形
print("Is square:", square.is_square())  # 应该返回 True,因为长度和宽度相等

在这个例子中,__is_square 和 __area 是私有属性,它们只能在 Rectangle 类的内部被访问和修改。__check_square 是一个私有方法,用于检查矩形是否是正方形,并更新 __is_square 属性。外部代码不能直接访问这些私有属性和方法,但可以通过公有方法 is_square 来检查矩形是否是正方形。这样做可以保护类的内部状态,并允许类控制如何访问和修改这些状态。

Python中的继承和多态

在面向对象编程中,继承(Inheritance)和多态(Polymorphism)是非常重要的概念。

下面我将结合之前提供的 Rectangle 类的代码,来解释这两个概念,并提供相应的代码示例。

继承(Inheritance)

继承是一种使一个类(称为子类或派生类)能够继承另一个类(称为基类或超类)的属性和方法的方式。这使得我们可以重用代码,并在现有类的基础上构建新的类。

下面是一个继承的例子,我们将创建一个 Square 类,它继承自 Rectangle 类:


# 继承自 Rectangle 的 Square 类
class Square(Rectangle):# 构造函数 __init__def __init__(self, side):# 调用基类 Rectangle 的构造函数,设置长度和宽度相等super().__init__(side, side)# Square 总是正方形,所以不需要检查 __is_squareself.__is_square = True# 重写基类的 calculate_area 方法,直接返回边长的平方def calculate_area(self):return self.length ** 2# 创建 Square 对象
square = Square(5)
# 通过 square 对象调用 print_area 方法。计算并打印出正方形的面积。
square.print_area()

在这个例子中,Square 类继承自 Rectangle 类。这意味着 Square 类继承了 Rectangle 类的所有属性和方法。Square 类的构造函数使用 super().init(side, side) 调用了 Rectangle 类的构造函数,并确保了正方形的边长相等。此外,Square 类还重写了 calculate_area 方法,因为正方形的面积计算可以简化为边长的平方。

多态(Polymorphism)

多态是指同一个方法在不同类型的对象上可以有不同的行为。在Python中,多态通常是通过继承和方法的覆盖(override)来实现的。

下面是一个多态的例子,我们将创建一个函数,它可以接受任何类型的 Rectangle 对象(包括 Square 对象),并调用它们的 calculate_area 方法:

def print_shape_area(shape):# 不关心 shape 是 Rectangle 还是 Square,只调用 calculate_area 方法print("Area:", shape.calculate_area())# 创建 Rectangle 对象
rect = Rectangle(10, 5)
# 创建 Square 对象
square = Square(5)# 使用相同的函数来打印不同形状的面积
print_shape_area(rect)  # 输出矩形的面积
print_shape_area(square)  # 输出正方形的面积

在这个例子中,print_shape_area 函数接受一个 shape 参数,该参数可以是任何 Rectangle 类型的对象。由于 Square 是 Rectangle 的子类,因此它也可以作为参数传递。当调用 shape.calculate_area() 时,根据 shape 的实际类型(Rectangle 或 Square),会调用相应类中的 calculate_area 方法。这就是多态性的体现:同一个方法名在不同的对象上有不同的行为。

通过继承和多态,我们可以创建可扩展和可维护的代码,因为它们允许我们在不修改现有代码的情况下添加新的功能和行为。

附件

本文对应的jupyter notebook源码链接,欢迎下载练习:https://download.csdn.net/download/fx_yzjy101/89775174

如有问题请留言。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vulnhub(12):bob 1.0.1(gpg文件解密)

端口 nmap主机发现 nmap -sn 192.168.72.0/24 ​ Nmap scan report for 192.168.72.169 Host is up (0.00020s latency). ​ 169是新出现的机器,他就是靶机 nmap端口扫描 nmap -Pn -sV 192.168.72.169 -p- --min-rate 10000 -oA nmap/scan 扫描开放端口保存到 nmap…

力扣最热一百题——除自身以外数组的乘积

目录 题目链接:238. 除自身以外数组的乘积 - 力扣(LeetCode) 题目描述 示例 提示: 解法一:左右数组(小型动态规划) 实现思路 Java写法: 运行时间 C写法: 运行时…

虚拟现实与PD协议快充

随着虚拟现实(VR)技术的不断进步,索尼的PlayStation VR2(简称PS VR2)凭借其卓越的性能和沉浸式体验,在游戏界引起了广泛关注。为了进一步拓展PS VR2的应用范围,索尼推出了PS VR2适配器&#xff…

IS-ISv4/6双栈

文章目录 IS-ISv4/6双栈实验要求配置 IS-ISv4/6双栈 实验要求 配置双栈 R1、2、3、4配置 IS-ISv4 和 IS-ISv6,配置IPv6多拓扑 上面为Level-1类型、中间为Level-1-2、下面是Level-2类型 还有就是说ATT位置1有一定要求连接L1/2连接L1或者L2类型路由器,至…

简单题94. 二叉树的中序遍历 (python)20240921

问题描述: #### python: # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution(…

统信服务器操作系统【搭建FTP】设置介绍

如何在操作系统上安装vsftp服务。设置匿名用户登录、设置授权用户密码访问功能,并介绍使用匿名方式、授权用户方式访问vsftp服务。本文适用于A、D、E三个服务器操作系统版本,除安装方式的差异,其他设置均相同。 文章目录 功能概述一、功能介绍二、准备环境三、安装步骤1. 在…

pg_start_backup

pg_start_backup()函数在主库上发起一个在线备份,命令执行成功后,将数据文件拷贝到备份接口中 select pg_start_backup(full0918,false,false); 以上会话不要关闭,复制数据目录。 cp -r /pgdata/data/postgres-f66f5f7a/ /opt/qfusion/mnt/st…

光伏开发:一分钟生成光伏项目报告

传统光伏项目报告的编制往往需要收集大量数据、进行复杂计算与分析,耗时长且易受人为因素影响。自动生成光伏项目报告,依托大数据、云计算、人工智能等先进信息技术,实现了对光伏项目关键参数的快速分析、评估与预测。 一、核心功能与流程 1…

Leetcode面试经典150题-39.组合总数

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如…

汇川AM400脉冲轴控制(轴控功能块ST源代码)

汇川AM400如何和编程软件通信连接 汇川AM400PLC如何和编程软件通信连接_汇川am400读取程序-CSDN博客文章浏览阅读159次。本文介绍了如何使用CODESYS编程软件与汇川AM400PLC进行通信连接,包括扫描网络、修改IP地址、刷新日志和下载监控程序的步骤。同时,文章提到了CODESYS编程…

python-3n+1数链/233

一:3n1数链题目描述 在计算机科学上,有很多类问题是无法解决的,我们称之为不可解决问题。然而,在很多情况下我们并不知道哪一类问题可以解决,哪一类问题不可解决。现在我们就有这样一个问题,问题如下&#…

DOG:知识图谱大模型问答的迭代交互式推理,克服长路径和假阳性关系挑战

DOG:知识图谱大模型问答的迭代交互式推理,克服长路径和假阳性关系挑战 秒懂大纲提出背景解法拆解全流程优化和医学关系 创意 秒懂大纲 ├── DoG框架【主题】 │ ├── 背景【研究背景】 │ │ ├── LLMs的局限性【问题描述】 │ │ │ …

go 读取excel

一、安装依赖 go get github.com/tealeg/xlsx二、main.go package mainimport "fmt" import "github.com/tealeg/xlsx"type Student struct {Name stringSex string }func (student Student) show() {fmt.Printf("Name:%s Sex:%s\r\n", stude…

消灭病毒gamedemo

DestoryVirus 一、AudioSourceManager using System.Collections; using System.Collections.Generic; using UnityEngine;public class AudioSourceManager : MonoBehaviour {public static AudioSourceManager Instance { get; private set; }public SoundPlayer soundPla…

JavaWeb初阶 day1

目录 tomcat目录结构 tomcat:web服务器软件 项目部署的方式 直接将项目放到webapps下 配置conf/server.xml文件 在conf\Catalina\localhost创建任意名称的xml文件。在文件中编写 静态项目和动态项目 Servlet Servlet执行原理 Servlet方法(生命周期&#x…

Linux入门学习:make/Makefile(Linux项目自动化构建工具)

文章目录 1. makefile文件语法2. make clean工程清理3. 细节语法4. make原理 ⭕背景: 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中&#xff0c…

Linux相关概念和重要知识点(5)(权限的修改、时间属性)

1.权限的修改 (1)提权行为 普通用户是会受到权限的限制,但root账户无视一切权限限制,因此当我们要获取更高的权限,有一种办法就是将自己变成root或者短暂拥有和root一样的权力。 普通用户 -> root :s…

C++QT医院专家门诊预约管理系统

目录 一、项目介绍 二、项目展示 三、源码获取 一、项目介绍 医院专家门诊预约管理系统 [要求] 该系统需创建和管理以下信息:1、门诊专家信息:专家姓名、编号、性别、年龄、职称、门诊科目、服务时间、门诊预约数据集等;2、门诊预约信息…

2024 研究生数学建模竞赛(E题)建模秘籍|高速公路应急车道紧急启用模型|文章代码思路大全

铛铛!小秘籍来咯! 小秘籍团队独辟蹊径,运用聚类分析,逻辑回归模型,决策树/规则,ARIMA等强大工具,构建了这一题的详细解答哦! 为大家量身打造创新解决方案。小秘籍团队,始…

Open3D 计算点云的曲率密度参数【2024最新版】

目录 一、算法原理1、曲率密度参数2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接,首发于:2024年9月21日。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的抄袭狗。 一、算法原理 1、曲率密度参数 对于点云数据集中任意一点 p i p_i