100天带你精通Python——第8天面向对象编程

请添加图片描述

文章目录

  • 前言
  • 面向对象技术简介
  • 类(Class)
  • 对象(Object)
  • 继承(Inheritance)
  • 封装(Encapsulation)
  • 多态(Polymorphism)
  • Python类详解
    • 静态变量(Static Variables)
    • 静态方法(Static Methods)
    • 抽象方法(Abstract Methods)
    • 方法重载(Method Overloading)
    • 方法重写(Method Overriding)
    • 魔法方法(Magic Methods)
  • 补充
  • 总结


前言

Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。

如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。

接下来我们先来简单的了解下面向对象的一些基本特征。


面向对象技术简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量:定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

类(Class)

类是 Python 中创建对象的蓝图。它定义了一组属性和方法,这些属性和方法将被用于创建对象。类本质上是一个模板,用于定义对象的结构和行为。

定义一个简单的类的例子

class Dog:def __init__(self, name, age):self.name = nameself.age = agedef bark(self):return f"{self.name} says woof!"# 创建一个 Dog 对象
my_dog = Dog(name="Buddy", age=3)# 调用对象的方法
print(my_dog.bark())  # 输出: Buddy says woof!

在这个例子中:

class Dog: 定义了一个类 Dog。
__init__: 是一个特殊的方法,用于初始化对象的属性。它在创建对象时被自动调用。
self: 代表类的实例,允许访问对象的属性和方法。
bark: 是类中的一个方法,它描述了对象的行为。

对象(Object)

对象是类的实例。每个对象都有自己独立的属性值,可以调用类中定义的方法。对象是类的具体实现。

创建和使用对象:

my_dog = Dog(name="Buddy", age=3)
print(my_dog.name)  # 输出: Buddy
print(my_dog.age)   # 输出: 3

继承(Inheritance)

继承是 OOP 的一个核心特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。继承有助于代码重用和扩展。

class Animal:def __init__(self, name):self.name = namedef speak(self):return "Some generic sound"class Dog(Animal):def speak(self):return f"{self.name} says woof!"# 创建一个 Dog 对象
my_dog = Dog(name="Buddy")
print(my_dog.speak())  # 输出: Buddy says woof!

在这个例子中:

Dog 类继承了 Animal 类。
Dog 类重写了 speak 方法,实现了多态。

封装(Encapsulation)

封装是将数据和操作这些数据的方法绑定在一起,隐藏内部实现细节,只暴露必要的接口。通过封装,类可以控制如何访问和修改其属

class Car:def __init__(self, brand, year):self.__brand = brand  # 私有属性self.__year = year    # 私有属性def get_brand(self):return self.__branddef set_brand(self, brand):self.__brand = brand# 创建一个 Car 对象
my_car = Car(brand="Toyota", year=2020)
print(my_car.get_brand())  # 输出: Toyota
my_car.set_brand("Honda")
print(my_car.get_brand())  # 输出: Honda

多态(Polymorphism)

多态允许不同类的对象以相同的方式调用同一方法,但具体行为可以根据对象的实际类型有所不同。这使得程序具有更好的灵活性和扩展性。

class Cat(Animal):def speak(self):return f"{self.name} says meow!"animals = [Dog(name="Buddy"), Cat(name="Whiskers")]for animal in animals:print(animal.speak())

Python类详解

静态变量(Static Variables)

静态变量(类变量)是属于类的变量,而不是类的实例。它们由所有实例共享。可以在类定义中直接声明静态变量。

class Counter:count = 0  # 静态变量def __init__(self):Counter.count += 1# 创建多个 Counter 对象
c1 = Counter()
c2 = Counter()
c3 = Counter()print(Counter.count)  # 输出: 3

静态方法(Static Methods)

静态方法是类的一部分,但它不依赖于类的实例。静态方法没有 self 参数,它不能访问类或实例的属性或方法。通常用于一些逻辑与类实例无关的功能。

class MathUtils:@staticmethoddef add(x, y):return x + y# 调用静态方法
result = MathUtils.add(5, 3)
print(result)  # 输出: 8

在这个例子中,add 是一个静态方法,它与 MathUtils 类的实例无关,可以直接通过类名调用。

抽象方法(Abstract Methods)

抽象方法是一个没有实现的方法,仅定义了方法的签名。抽象方法通常用于定义一个接口,强制子类实现这些方法。抽象方法需要与抽象基类(abc.ABC)结合使用。

from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef area(self):passclass Rectangle(Shape):def __init__(self, width, height):self.width = widthself.height = heightdef area(self):return self.width * self.height# 创建一个 Rectangle 对象
rect = Rectangle(width=4, height=5)
print(rect.area())  # 输出: 20

在这个例子中:

Shape 是一个抽象基类,其中定义了一个抽象方法 area。
Rectangle 类继承自 Shape,并实现了 area 方法。

方法重载(Method Overloading)

在许多编程语言中,方法重载指的是在同一个类中定义多个同名但参数列表不同的方法。Python 不支持传统的重载机制,即无法定义多个同名的方法,参数列表不同的方法会导致最后定义的方法覆盖之前定义的所有方法。

class MathUtils:def add(self, a, b):return a + b# 这会覆盖之前的方法定义def add(self, a, b, c=0):return a + b + c# 创建一个 MathUtils 对象
utils = MathUtils()
print(utils.add(2, 3))      # 输出: 5
print(utils.add(2, 3, 4))   # 输出: 9

在这个例子中,第二个 add 方法定义覆盖了第一个 add 方法。Python 通过参数默认值或使用可变参数来模拟重载功能

模拟重载

class MathUtils:def add(self, *args):return sum(args)# 创建一个 MathUtils 对象
utils = MathUtils()
print(utils.add(2, 3))        # 输出: 5
print(utils.add(2, 3, 4))     # 输出: 9
print(utils.add(2, 3, 4, 5))  # 输出: 14

在这个例子中,*args 允许方法接受任意数量的参数,从而模拟了方法重载。

方法重写(Method Overriding)

方法重写是指在子类中重新定义父类的方法,以改变或扩展父类的行为。方法重写使得子类可以提供特定的实现来替代从父类继承的方法

class Animal:def speak(self):return "Some generic sound"class Dog(Animal):def speak(self):return "Woof!"class Cat(Animal):def speak(self):return "Meow!"# 创建对象
animals = [Dog(), Cat()]for animal in animals:print(animal.speak())

在这个例子中,Dog 和 Cat 类重写了 Animal 类中的 speak 方法。每个子类提供了自己特定的实现。

魔法方法(Magic Methods)

魔法方法(或称为特殊方法)是以双下划线 __ 开头和结尾的方法,用于实现 Python 中的运算符重载和特殊功能。常见的魔法方法包括__init__、__str__、__repr__、__len__、__getitem__ 和 __setitem__等。

class Point:def __init__(self, x, y):self.x = xself.y = ydef __str__(self):return f"Point({self.x}, {self.y})"def __repr__(self):return f"Point(x={self.x}, y={self.y})"def __eq__(self, other):if isinstance(other, Point):return self.x == other.x and self.y == other.yreturn Falsedef __add__(self, other):if isinstance(other, Point):return Point(self.x + other.x, self.y + other.y)return NotImplemented# 创建 Point 对象
p1 = Point(2, 3)
p2 = Point(4, 5)print(p1)          # 输出: Point(2, 3)
print(repr(p1))    # 输出: Point(x=2, y=3)
print(p1 == p2)    # 输出: False
print(p1 + p2)     # 输出: Point(6, 8)

在这个例子中:

__init__ 用于初始化对象。
__str__ 用于返回对象的字符串表示,通常用于 print。
__repr__ 用于返回对象的官方字符串表示,通常用于调试。
__eq__ 用于比较两个对象是否相等。
__add__ 用于实现加法操作。
以下还有更多的魔法方法
实例化和初始化
__new__(cls, *args, **kwargs): 创建一个新实例,通常用于实现单例模式或自定义实例化行为。
__init__(self, *args, **kwargs): 初始化实例对象,设置实例的初始状态。
字符串表示
__str__(self): 返回对象的“用户友好”字符串表示,通常用于 print() 函数。
__repr__(self): 返回对象的“官方”字符串表示,通常用于调试和开发者查看。
比较操作
__eq__(self, other): 实现 == 操作符。
__ne__(self, other): 实现 != 操作符。
__lt__(self, other): 实现 < 操作符。
__le__(self, other): 实现 <= 操作符。
__gt__(self, other): 实现 > 操作符。
__ge__(self, other): 实现 >= 操作符。
数学运算
__add__(self, other): 实现 + 操作符。
__sub__(self, other): 实现 - 操作符。
__mul__(self, other): 实现 * 操作符。
__truediv__(self, other): 实现 / 操作符。
__floordiv__(self, other): 实现 // 操作符。
__mod__(self, other): 实现 % 操作符。
__pow__(self, other): 实现 ** 操作符。
容器协议
__len__(self): 返回容器对象的长度,支持 len() 函数。
__getitem__(self, key): 实现索引操作,如 obj[key]。
__setitem__(self, key, value): 实现索引赋值操作,如 obj[key] = value。
__delitem__(self, key): 实现索引删除操作,如 del obj[key]。
__iter__(self): 返回迭代器对象,支持迭代。
__next__(self): 在迭代器对象中返回下一个值。
可调用对象
__call__(self, *args, **kwargs): 使对象像函数一样可调用。
上下文管理
__enter__(self): 在上下文管理器中,进入上下文时调用。
__exit__(self, exc_type, exc_value, traceback): 在上下文管理器中,退出上下文时调用。
其他常见魔法方法
__copy__(self): 返回对象的浅拷贝。
__deepcopy__(self, memo): 返回对象的深拷贝。
__contains__(self, item): 实现 in 操作符。
__contains__(self, item): 实现 in 操作符。
__hash__(self): 实现哈希值,通常用于哈希表(如字典和集合)中的键。
__delattr__(self, name): 实现 delattr() 函数,删除对象属性。
__getattr__(self, name): 在访问不存在的属性时调用。
__setattr__(self, name, value): 实现属性赋值。
__dir__(self): 返回对象的属性列表,通常用于 dir() 函数。

补充

dataclass 装饰器是 Python 3.7 引入的一个非常有用的工具,用于简化类的定义,特别是那些主要用于存储数据的类。它可以自动为类生成一些常见的方法,如 __init____repr____eq__ 等。使用 dataclass 可以让你更方便地创建数据容器类,同时减少样板代码。

from dataclasses import dataclass, field
from typing import List@dataclass
class Student:name: strgrades: List[int] # 创建多个 Student 对象
student1 = Student(name="Alice")
student2 = Student(name="Bob")# 修改一个实例的 grades 属性
student1.grades.append(90)# 打印两个实例
print(student1)  # 输出: Student(name='Alice', grades=[90])
print(student2)  # 输出: Student(name='Bob', grades=[])  # 不会被修改

总结

类是面向对象编程的核心概念,它提供了一个模板用于创建对象。类定义了对象的属性(数据)和方法(行为),并通过构造函数 (init) 初始化对象的状态。通过实例化类,可以创建多个对象,每个对象拥有独立的属性和方法。

面向对象编程(OOP)是一种编程范式,通过将数据和操作数据的方法封装在对象中,来组织和管理代码。OOP 的核心概念包括:

  • 封装: 将数据和操作数据的方法结合在一起,隐藏内部实现细节,只暴露必要的接口。
  • 继承: 允许一个类(子类)继承另一个类(父类)的属性和方法,支持代码重用和扩展。
  • 多态: 允许不同类的对象通过相同的接口进行交互,使得代码更具灵活性。
  • 抽象: 定义一个接口,而不具体实现细节,强制子类实现接口中的方法。

通过这些特性,面向对象编程帮助开发者构建结构清晰、易于维护和扩展的代码。

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

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

相关文章

day39(8/29)——harbor私有仓库管理

一、harbor私有仓库管理 是python的包管理工具&#xff0c;和yum对redhat的关系是一样的 yum -y install epel-release yum -y install python2-pip pip install --upgrade pip pip list pip 8x pip install --upgrade pip pip install --upgrade pip20.3 -i https://mirror…

应用层(Web与HTTP)

目录 常见术语 1.HTTP概况 2.HTTP连接 非持久HTTP流程 响应时间模型 持久HTTP 3.HTTP报文 3.1HTTP请求报文 3.2HTTP响应报文 HTTP响应状态码 4.Cookies&#xff08;用户-服务器状态&#xff09; cookies&#xff1a;维护状态 Cookies的作用 5.Web缓冲&#xff08;…

yolo格式数据集|自动驾驶|5类别|数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用

本数据为自动驾驶检测数据集&#xff0c;数据集是车类摄像头在不同场景下拍摄&#xff0c;有5类&#xff0c;分别为car、truck、person、bicycle、traffic_light。数据集整理不易&#xff0c;获取地址在最后。 数据集数量如下&#xff1a; 总共有:18000张 训练集&#xff1a;14…

【卷起来】VUE3.0教程-01-环境搭建与安装

​分享不易&#xff0c;耗时耗力&#xff0c;麻烦给个不要钱的关注和赞吧 &#x1f332; 什么是VUE Vue 是一个框架&#xff0c;也是一个生态。其功能覆盖了大部分前端开发常见的需求。但 Web 世界是十分多样化的&#xff0c;不同的开发者在 Web 上构建的东西可能在形式和规模…

算法-最长连续序列

leetcode的题目链接 这道题的思路主要是要求在O&#xff08;n)的时间复杂度下&#xff0c;所以你暴力解决肯定不行&#xff0c;暴力至少两层for循环&#xff0c;所以要在O&#xff08;n)的时间复杂度下&#xff0c;你可以使用HashSet来存储数组&#xff0c;对于每个数字&#…

给鼠标一个好看的指针特效 鼠标光标如何修改形状?

许多爱美的小伙伴们都想着如何给自己的电脑打扮一下&#xff0c;用各种各样的途径来美化我们的电脑。今天我们给大家分享一下&#xff0c;如何美化鼠标效果&#xff0c;给鼠标指针修改成一个非常好看的形状~ 一起来看几组鼠标的效果&#xff0c;小编我给大家做了个录屏&#x…

YoloV8实战:使用YoloV8实现OBB框检测

定向边框(OBB)数据集概述 使用定向边界框(OBB)训练精确的物体检测模型需要一个全面的数据集。本文解释了与Ultralytics YOLO 模型兼容的各种 OBB 数据集格式,深入介绍了这些格式的结构、应用和格式转换方法。数据集使用DOTA。 YOLO支持的 OBB 格式 在Ultralytics YOLO …

AI编码新时代:免费人工智能助手Blackbox AI

前言&#xff1a; 在当今快速发展的科技时代&#xff0c;人工智能已经渗透到我们生活的方方面面&#xff0c;从智能手机的语音助手到智能家居控制系统&#xff0c;再到在线客服和个性化推荐算法&#xff0c;AI智能工具正变得越来越普遍。它们以其高效、智能和用户友好的特性&am…

git常见命令行及分支规范

文章目录 GIT常见命令行原理图基本设置初始化和克隆仓库文件管理提交更改查看状态和历史分支管理远程仓库交互高级功能GIT常见分支风格1. 单一主干分支(Single Main Branch)//极少使用优点:缺点:2. 多主干分支(Multiple Main Branches)//个人小型项目采用优点:缺点:3. …

redis的共享session应用

项目背景&#xff1a; 该项目背景就是黑马的黑马点评项目。 一&#xff1a;基于Session实现验证码登录流程 基本的登录流程我们做了很多了。这个是短信登录流程 其实和普通的登录流程就多了一个生成验证码&#xff0c;并将验证码保存在session中&#xff0c;并且呢&#xf…

《JavaEE进阶》----1.<JavaEE进阶可以学到什么>

本篇博客会讲到 一、JavaEE进阶学习内容&#xff1a; 1.框架的学习&#xff1a;Spring、Spring Boot、Spring MVC、MyBatis 2.大项目实践 3.源码阅读 二、JavaEE简介 B/S架构web开发流程 web前端开发&#xff08;了解&#xff09; web后端开发&#xff08;重点&#xff09; 三、…

【C++】OJ习题 篇2

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1、删除有序数组中的重复项&#x1f4a5;2、数组中出现次数超过一半的数字&#x1f4a5;3、最…

【Python进阶】学习Python必须要安装PyCharm。一篇文章带你总结一下安装PyCharm的注意事项,文末附带PyCharm激活码!!!

PyCharm激活码&#xff08;文末附带精品籽料&#xff09;&#xff1a; K384HW36OB-eyJsaWNlbnNlSWQiOiJLMzg0SFczNk9CIiwibGljZW5zZWVOYW1lIjoibWFvIHplZG9uZyIsImxpY2Vuc2VlVHlwZSI6IlBFUlNPTkFMIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdG…

代码随想录算法训练营day58:图论08:拓扑排序精讲;dijkstra(朴素版)精讲

拓扑排序精讲 卡码网&#xff1a;117. 软件构建(opens new window) 题目描述&#xff1a; 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依…

Unity 动态光照贴图,加载后显示变暗或者变白问题 ReflectionProbe的使用

动态加载光照贴图代码&#xff0c;可参考这个帖子 Unity 预制动态绑定光照贴图遇到变白问题_unity urp 动态加载光照信息 变黑-CSDN博客 这次遇到的问题是&#xff0c;在编辑器下光照贴图能正常显示&#xff0c;打出apk后光照贴图加载后变黑的问题 以下4张图代表4种状态&…

计算机毕业设计 基于SpringBoot框架的网上蛋糕销售系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

MATLAB生成mif文件

MATLAB代码 % 参数设置 N 4096; % 数据点数量 t linspace(0, 2*pi, N); % 时间向量 width 12; % 位宽% 正弦波 sine_wave 2.5 * sin(t) 2.5; % 幅度在0到5之间% 三角波 tri_wave 5 - abs(mod(t/(2*pi)*4, 2) - 1);% 方波 square_wave 2.5 * (square(t) 1); % 将范围调…

安嘉空间:智慧科技守护空间健康

在当今社会&#xff0c;随着人们对生活质量要求的不断提升&#xff0c;室内环境的健康与安全问题日益受到重视。安嘉空间&#xff0c;作为一家致力于人居健康空间技术研发的高科技企业&#xff0c;以其独创的技术和卓越的产品&#xff0c;为广大用户提供了一套全面的空间健康解…

VastBase——数据库参数调优

一、内存参数调优 数据库的复杂查询语句性能非常强的依赖于数据库系统内存的配置参数。数据库系统内存的配置参数主要包括逻辑内存管理的控制参数和执行算子是否下盘的参数&#xff1a; 1.逻辑内存管理参数&#xff1a;max_process_memory max_process_memory – shared memo…

STM32 - 笔记3

1 开发有基于寄存器和HAL库 在开发 STM32 系列微控制器时&#xff0c;你可以选择基于寄存器的开发方法或使用 STM32 HAL&#xff08;硬件抽象层&#xff09;库进行开发。两者各有优缺点&#xff0c;适用于不同的场景和开发需求。下面详细介绍两种方法的特点、使用场景以及示例…