python 中面向对象编程:深入理解封装、继承和多态

在本章中,我们将深入探讨Python中的高级面向对象编程概念,包括封装、继承和多态。让我们开始吧!

目录

    • 面向对象简介
      • 类和实例
      • 属性和方法
      • 继承和多态
    • 高级面向对象概念
      • 私有变量
      • 使用 `@property`
      • 使用 `__slots__`
      • 类的特殊成员
        • `__doc__`
        • `__call__`
        • `__str__`
        • `__iter__`
        • `__getitem__`, `__setitem__`, `__delitem__`

面向对象简介

面向对象编程(OOP)是一种编程范式,它通过将数据和方法封装在对象中,使代码更加模块化和易于管理。通过这种方式,我们可以避免重复造轮子,提升代码的可维护性和可读性。
image.png

类和实例

在OOP中,类是对某类对象的抽象,而实例是类的具体对象。例如,我们可以定义一个Human类来抽象表示人,并通过实例化该类来创建具体的人对象。

class Human:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def hello(self):
        print(f"Hello, I'm {self.name}")

person1 = Human("Yingshan", 25)
person2 = Human(name="Lee", age=23)

person1.hello()  # 输出: Hello, I'm Yingshan
person2.hello()  # 输出: Hello, I'm Lee

image.png

属性和方法

类的属性是类中定义的数据,而方法是类中定义的函数。在上面的例子中,nameage是属性,hello是方法。
image.png

继承和多态

继承是OOP的核心概念之一,通过继承,我们可以创建一个新类,该类继承自现有的类,获得其所有属性和方法。例如,我们可以创建一个Animal类,然后让Human类继承自Animal类。
image.png

class Animal:
    def mobile(self):
        return "Yes, animals are mobile"

class Human(Animal):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def hello(self):
        print(f"Hello, I'm {self.name}")

human = Human("Yingshan", 25)
print(human.mobile())  # 输出: Yes, animals are mobile

多态允许我们通过父类引用来调用子类的方法。在Python中,这可以通过方法重写实现。例如:

class Animal:
    def mobile(self):
        return "Yes, this animal is mobile"

class Human(Animal):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def hello(self):
        print(f"Hello, I'm {self.name}")

    def mobile(self):
        return "Yes, this person is mobile"

human = Human("Yingshan", 25)
print(human.mobile())  # 输出: Yes, this person is mobile

高级面向对象概念

私有变量

在类中,通过在变量名前加双下划线,可以将变量设为私有变量,仅在类内部访问。

class Person:
    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

person = Person("XiaoYang")
print(person.get_name())  # 输出: XiaoYang
# print(person.__name)  # 会报错,无法直接访问私有变量

使用 @property

使用 @property 装饰器,我们可以将方法转换为属性,从而更自然地访问和修改类的属性。
image.png

class Person:
    def __init__(self, weight):
        self.__weight = weight

    @property
    def weight(self):
        return self.__weight

    @weight.setter
    def weight(self, value):
        if value < 100:
            print("Too light!")
        elif value > 400:
            print("Too heavy!")
        else:
            self.__weight = value

p1 = Person(160)
print(p1.weight)  # 输出: 160
p1.weight = 450   # 输出: Too heavy!

使用 __slots__

为了限制实例的属性,我们可以使用 __slots__。这可以节省内存空间。
image.png

class Person:
    __slots__ = ('name', 'country')

p1 = Person()
p1.name = "XiaoYang"
p1.country = "China"
# p1.weight = 160  # 会报错,`weight` 不在 `__slots__` 中

类的特殊成员

__doc__

__doc__ 表示类的文档字符串。

class Person:
    """
    This is a person class.
    """
    def __init__(self, name):
        self.__name = name

print(Person.__doc__)
__call__

通过定义 __call__ 方法,可以使对象变得可调用。

class Person:
    def __init__(self, name):
        self.__name = name

    def __call__(self):
        print("Calling myself")

yingshan = Person("Yingshan")
yingshan()  # 输出: Calling myself
__str__

__str__ 方法定义了对象的字符串表示。

class Person:
    def __init__(self, name):
        self.__name = name

    def __str__(self):
        return f"This is {self.__name}"

yingshan = Person("Yingshan")
print(yingshan)  # 输出: This is Yingshan
__iter__

通过定义 __iter__ 方法,可以将对象变为可迭代。

class Person:
    def __init__(self, names):
        self.__names = names

    def __iter__(self):
        return iter(self.__names)

friends = Person(["Yingshan", "Mike", "Tim"])
for friend in friends:
    print(friend)  # 依次输出: Yingshan, Mike, Tim
__getitem__, __setitem__, __delitem__

这些方法用于索引操作。

class Person:
    def __init__(self):
        self.dic = {}

    def __setitem__(self, key, value):
        self.dic[key] = value

    def __getitem__(self, key):
        return self.dic[key]

    def __delitem__(self, key):
        del self.dic[key]

obj = Person()
obj["name"] = "Yingshan"
print(obj["name"])  # 输出: Yingshan
del obj["name"]

通过面向对象编程,复杂的问题变得更易于解决。

希望这篇文章能帮助你更好地理解Python中的面向对象编程。Happy coding!

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

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

相关文章

MindSpore中NumPy变量转换为Tensor张量使用的Tensor.from_numpy()函数到底是深拷贝还是浅拷贝

在NumPy转换为Tensor使用的Tensor.from_numpy()函数到底是深拷贝还是浅拷贝 使用Tensor()将NumPy变量转换为Tensor变量。 类似数组转换张量的方法 n np.ones(5) t Tensor.from_numpy(n) print(f"t: {t}", type(t)) np.add(n, 1, outn) print(f"n: {n}"…

使用 LangServe 构建和部署 MinIO 支持的 LangChain Agent API

我们在LangChain的创新世界中的旅程揭示了其在转变数据管理和应用程序功能方面的强大能力。 通过之前的讨论&#xff0c;我们深入探讨了几个主题&#xff0c;同时探索了LangChain的复杂功能。在本文中&#xff0c;我们将以“使用 MinIO 赋能 Langchain 代理”中涵盖的概念为基…

postgres数据库的流复制

1. 流复制和逻辑复制的差异 逻辑复制和流复制最直观的不同是&#xff0c;逻辑复制支持表级别复制区分点事原理不同 逻辑日志是在wal日志产生的数据库上&#xff0c;由逻辑解析模块对wal日志进行初步的解析&#xff0c;解析结果是ReorderBufferChange&#xff08;理解为HeapTup…

SpringBoot整合拦截器和日期转换器

一、SpringBoot整合拦截器 1.添加拦截器 package com.by.interceptor;import com.by.pojo.User; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import java…

BaseMapper 接口介绍

基于 mybatis-mapper/provider 核心部分实现的基础的增删改查操作&#xff0c;提供了一个核心的 io.mybatis.mapper.BaseMapper 接口和一个 预定义 的 io.mybatis.mapper.Mapper 接口&#xff0c;BaseMapper 接口定义如下&#xff1a; /*** 基础 Mapper 方法&#xff0c;可以在…

React useImperativeHandle Hook

useImperativeHandle Hook 是一个比较比较简单的 hook&#xff0c;为 ref 节点添加一些处理方法&#xff0c;下面是来自官网例子&#xff0c;为 ref 添加了两个方法。 import { forwardRef, useRef, useImperativeHandle } from react;const MyInput forwardRef(function MyI…

香港办公室顺利落地,量子之歌发布白皮书开启银发新篇章

6月25日&#xff0c;量子之歌香港办公室开业典礼暨《2023年中国中老年服务市场白皮书&#xff1a;银发经济&#xff0c;耀眼的黄金赛道》发布会于香港中环交易广场隆重开幕。 这一里程碑事件不仅彰显了量子之歌在银发经济领域的行业领军者风范&#xff0c;更凸显了其在专业服务…

一文了解自定义表单系统开源的多个优势

降本、提质、增效&#xff0c;是当前很多企业都想实现的目的。什么样的软件可以助力企业创造价值&#xff1f;低代码技术平台是近些年得到了很多客户喜爱的平台产品&#xff0c;因为它能帮助大家减少编程代码的撰写&#xff0c;能轻松助力各部门之间做好协调沟通工作&#xff0…

算法导论 总结索引 | 第四部分 第十六章:贪心算法

1、求解最优化问题的算法 通常需要经过一系列的步骤&#xff0c;在每个步骤都面临多种选择。对于许多最优化问题&#xff0c;使用动态规划算法求最优解有些杀鸡用牛刀了&#xff0c;可以使用更简单、更高效的算法 贪心算法&#xff08;greedy algorithm&#xff09;就是这样的算…

13.1 Go 反射(Reflection)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

文本生成图像综述

本调查回顾了扩散模型在生成任务中广泛流行的背景下文本到图像的扩散模型。作为一份自成一体的作品&#xff0c;本调查首先简要介绍了基本扩散模型如何用于图像合成&#xff0c;然后介绍了条件或指导如何改善学习。基于这一点&#xff0c;我们介绍了文本到图像生成方面的最新方…

条码二维码读取设备在医疗设备自助服务的重要性

医疗数字信息化建设的深入推进&#xff0c;医疗设备自助服务系统已成为医疗服务领域的一大趋势&#xff0c;条码二维码读取设备作为自助设备的重要组成部分&#xff0c;通过快速、准确地读取条形码二维码信息&#xff0c;不公提升了医疗服务效率&#xff0c;还为患者提供了更加…

Flutter页面状态保留策略

目的: 防止每次点击底部按钮都进行一次页面渲染和网络请求 1. 使用IndexedStack 简单,只需要把被渲染的组件外部套一层IndexedStack即可 缺点: 在应用启动的时候,所有需要保存状态的页面都会直接被渲染,保存起来. 对性能有影响 2. 使用PageController 实现较为复杂,但是不用…

Biome-BGC生态系统模型与Python融合技术

Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。 在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天…

C++设计模式——Facade外观模式

一&#xff0c;外观模式简介 外观模式是一种结构型设计模式&#xff0c; 又称为门面模式&#xff0c;也是一种基于创建对象来实现的模式&#xff0c;为子系统中的各组接口的使用提供了统一的访问入口。 外观模式对外提供了一个对象&#xff0c;让外部客户端(Client)对子系统的…

dataguard 主备切换方式switchover 和 failover 操作步骤

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享。datagu…

【ATU Book - i.MX8系列 - OS】NXP i.MX Linux Desktop (Ubuntu) BSP 开发环境架设

一、概述 谈论嵌入式系统的开发环境&#xff0c;不得不提起近年来相当实用的 Yocto 建构工具。此工具拥有极为灵活的平台扩展性&#xff0c;广泛的软体套件与社群支持、多平台支援整合性&#xff0c;能够满足开发者特定需求和多种热门的嵌入式系统架设&#xff0c;已成为当今顶…

【深海王国】小学生都能玩的单片机?零基础入门单片机Arduino带你打开嵌入式的大门!(10)

Hi٩(๑o๑)۶, 各位深海王国的同志们&#xff0c;早上下午晚上凌晨好呀~辛勤工作的你今天也辛苦啦 (o゜▽゜)o☆ 今天大都督继续为大家带来系列——小学生都能玩的单片机&#xff01;带你一周内快速走进嵌入式的大门&#xff0c;let’s go&#xff01; &#xff08;10&#…

Java学习笔记(多线程):CompetableFuture

本文是自己的学习笔记&#xff0c;主要参考资料如下 https://www.cnblogs.com/dolphin0520/p/3920407.html JavaSE文档 https://blog.csdn.net/ThinkWon/article/details/102508721 1、Overview2、重要参数3、主要方法3.1、创建实例&#xff0c;获取返回值3.2、线程执行顺序相关…

三十九篇:UML与SysML:掌握现代软件和系统架构的关键

UML与SysML&#xff1a;掌握现代软件和系统架构的关键 1. 引言 1.1 为什么系统设计如此关键 在当今快速发展的技术环境中&#xff0c;系统设计的重要性不言而喻。无论是软件开发还是复杂的系统工程&#xff0c;良好的设计是确保项目成功的基石。系统设计不仅关系到功能的实现…