当前位置: 首页 > article >正文

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 = length
        self.width = width
    
    def calculate_area(self):
        return self.length * self.width
    
    def 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 = length
        self.width = width
        # 私有属性,表示矩形是否是正方形
        self.__is_square = length == width
        # 私有属性,存储计算过的面积,避免重复计算
        self.__area = None

    # 公有方法,计算面积
    def calculate_area(self):
        # 如果私有属性 __area 已经有值,直接返回
        if self.__area is not None:
            return self.__area
        # 计算面积并赋值给私有属性 __area
        self.__area = self.length * self.width
        return 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.width
        return 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_square
        self.__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.kler.cn/a/312394.html

相关文章:

  • Flutter Getx状态管理
  • Vue7种组件之间通信方式
  • Chromium 中MemoryMappedFile使用例子c++
  • 哪款开放式耳机好用?5款实力出众的开放式耳机按头安利!
  • Ubuntu20.4系统编译瑞芯微RK3568 SDK
  • ORA-01092 ORA-14695 ORA-38301
  • 【LeetCode】每日一题 2024_9_17 公交路线(BFS)
  • Effective Java 学习笔记45-48 Stream
  • VS code 查看 ${workspaceFolder} 目录指代路径
  • 设计模式-行为型模式-解释器模式
  • Python 解析 Charles JSON Session File (.chlsj)
  • 攻防世界--->gametime
  • 数据结构-2.7.单链表的查找与长度计算
  • linux-系统管理与监控-磁盘管理
  • mysql学习教程,从入门到精通,SQL DISTINCT 子句 (16)
  • DeDeCMS靶场漏洞复现
  • 前端vue-父传子
  • 2024年亲测好用的四大在线翻译工具大盘点!
  • keras和tensorflow可用的一组版本
  • 【百日算法计划】:每日一题,见证成长(013)
  • MySQL练手题--获得最近第二次的活动(困难)
  • 【JVM】符号引用 和 直接引用
  • 中国计算机学会(CCF)推荐中文科技期刊目录(2019年)
  • nacos报Client not connected, current status:STARTING
  • Stable Diffusion绘画 | ControlNet应用-IP-Adapter:堪比 Midjourney 垫图
  • Ubuntu在CMakeLists.txt中指定OpenCV版本的参考方法