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

【Python】Python 面向对象编程详解​

Python 面向对象编程详解​


文章目录

  • Python 面向对象编程详解​
  • 前言
  • 一、面向对象的基本概念​
    • 1.1 类(Class)​
    • 1.2 对象(Object)​
    • 1.3 属性(Attribute)​
    • 1.4 方法(Method)​
  • 二、类的定义与对象的创建​
    • 2.1 类的定义​
    • 2.2 对象的创建​
  • 三、构造方法与属性初始化​
    • 3.1 构造方法的语法
    • 3.2 构造方法的使用举例
    • 3.3 带有默认参数的构造方法​
  • 四、类的属性和方法分类​
    • 4.1 属性分类​
    • 4.2 方法分类​
  • 五、继承​
    • 5.1 单继承​
    • 5.2 多继承​
  • 六、封装与访问控制​
  • 七、多态​
  • 总结​


前言

面向对象编程(Object-Oriented Programming,简称 OOP)是一种重要的编程范式,它将数据和操作数据的方法封装在一起,以对象为核心来组织代码。Python 作为一门支持面向对象编程的语言,提供了简洁而强大的面向对象特性,让开发者能够更高效地构建复杂应用。


一、面向对象的基本概念​

1.1 类(Class)​

类是对具有相同属性和方法的一类事物的抽象描述,它定义了该类对象所共有的属性和方法。可以把类看作是一个模板,通过这个模板可以创建出具体的对象。类不仅包含了数据(属性),还包含了操作这些数据的函数(方法),这使得数据和操作能够紧密结合。​

例如,“汽车” 可以看作一个类,它具有颜色、品牌、型号、发动机排量等属性,还有行驶、刹车、转弯、加速等方法。这些属性和方法是所有汽车都具备的共性特征,只是不同汽车的属性值和方法的具体表现可能不同。

1.2 对象(Object)​

对象是类的实例化结果,是具体存在的事物。一个类可以创建出多个对象,每个对象都具有该类所定义的属性和方法,但属性的值可能不同。对象是类的具体体现,通过对象可以实现类所定义的功能。​

例如,根据 “汽车” 类,可以创建出 “一辆红色的特斯拉 Model 3,发动机排量为 2.0T”“一辆黑色的宝马 X5,发动机排量为 3.0T” 等具体的汽车对象。这些对象都属于 “汽车” 类,但各自的属性值不同,执行方法时的表现也可能有所差异。

1.3 属性(Attribute)​

属性是类或对象所具有的特征,用于描述对象的状态。在类中定义的属性是该类所有对象共有的特征,每个对象可以有不同的属性值。属性可以分为不同的类型,如基本数据类型(整数、字符串、布尔值等)、复合数据类型(列表、字典、元组等),甚至可以是其他对象。​

例如,“汽车” 类的 “颜色” 属性可以是字符串类型(如 “红色”“黑色”),“发动机排量” 属性可以是浮点数类型(如 2.0、3.0)。

1.4 方法(Method)​

方法是类中定义的函数,用于描述对象的行为,即对象可以执行的操作。方法可以操作类或对象的属性,实现特定的功能。与普通函数不同,方法需要通过类或对象来调用,并且方法中通常包含一个特殊的参数(如self、cls),用于引用类或对象本身。​

例如,“汽车” 类的 “行驶” 方法可以改变汽车的位置属性,“加速” 方法可以提高汽车的速度属性。

类与对象关系示意图:​
类与对象关系示意图


二、类的定义与对象的创建​

2.1 类的定义​

在 Python 中,使用class关键字来定义类,基本语法如下:​

class 类名:# 类的属性定义类属性1 =1类属性2 =2# ...# 类的方法定义def 方法名1(self, 参数1, 参数2, ...):# 方法体passdef 方法名2(self, 参数1, 参数2, ...):# 方法体pass# ...​

其中,类名通常采用驼峰命名法(每个单词的首字母大写,不使用下划线),这是 Python 中类命名的惯例,便于区分类和函数。类属性是该类所有对象共有的属性,定义在方法之外;方法定义在类内部,第一个参数通常是self,用于引用实例对象。

2.2 对象的创建​

创建对象的过程称为实例化,只需使用类名加括号即可。在实例化时,可以根据类的构造方法(如果有的话)传递参数,用于初始化对象的属性。

举例:​

# 定义汽车类
class Car:# 类的属性category = "交通工具"  # 所有汽车都属于交通工具类别color = "白色"  # 默认颜色为白色brand = "未知品牌"model = "未知型号"# 类的方法def drive(self):"""描述汽车行驶的行为"""print(f"{self.brand}{self.model}正在道路上行驶")def brake(self):"""描述汽车刹车的行为"""print(f"{self.brand}{self.model}正在刹车,车速逐渐降低")def accelerate(self, speed_increase):"""描述汽车加速的行为,参数为增加的速度"""print(f"{self.brand}{self.model}加速,速度增加了{speed_increase}km/h")# 创建汽车对象
car1 = Car()
car2 = Car()# 访问对象的属性
print(f"car1的颜色:{car1.color}")  # 输出:car1的颜色:白色
print(f"car2的品牌:{car2.brand}")  # 输出:car2的品牌:未知品牌
print(f"car1的类别:{car1.category}")  # 输出:car1的类别:交通工具# 修改对象的属性值
car1.color = "红色"
car1.brand = "特斯拉"
car1.model = "Model 3"
car2.color = "黑色"
car2.brand = "宝马"
car2.model = "X5"print(f"修改后car1的颜色:{car1.color}")  # 输出:修改后car1的颜色:红色
print(f"修改后car2的品牌:{car2.brand}")  # 输出:修改后car2的品牌:宝马# 调用对象的方法
car1.drive()  # 输出:特斯拉Model 3正在道路上行驶
car2.brake()  # 输出:宝马X5正在刹车,车速逐渐降低
car1.accelerate(20)  # 输出:特斯拉Model 3加速,速度增加了20km/h

三、构造方法与属性初始化​

为了在创建对象时能够为对象的属性赋初始值,避免创建对象后再逐个修改属性的繁琐操作,Python 提供了构造方法__init__。构造方法是一种特殊的方法,在对象被创建时自动调用,用于初始化对象的属性。

3.1 构造方法的语法

class 类名:def __init__(self, 参数1, 参数2, ..., 参数n):# 初始化实例属性self.属性1 = 参数1self.属性2 = 参数2# ...self.属性n = 参数n# 其他方法定义

其中,self代表类的实例对象,在调用方法时不需要手动传递,Python 会自动将当前对象作为self参数传递给方法。参数 1 到参数 n 是用于初始化对象属性的值,在创建对象时需要传递这些参数。

3.2 构造方法的使用举例

class Car:# 类属性category = "交通工具"def __init__(self, color, brand, model, displacement):"""构造方法,初始化汽车的颜色、品牌、型号和发动机排量属性"""self.color = colorself.brand = brandself.model = modelself.displacement = displacement  # 发动机排量def drive(self):print(f"{self.color}{self.brand}{self.model}(排量{self.displacement}T)正在行驶")def get_info(self):"""获取汽车的详细信息"""return f"汽车信息:颜色-{self.color},品牌-{self.brand},型号-{self.model},排量-{self.displacement}T"# 创建对象时传递参数,初始化属性
car1 = Car("红色", "特斯拉", "Model 3", 2.0)
car2 = Car("黑色", "宝马", "X5", 3.0)car1.drive()  # 输出:红色的特斯拉Model 3(排量2.0T)正在行驶
print(car2.get_info())  # 输出:汽车信息:颜色-黑色,品牌-宝马,型号-X5,排量-3.0T

在上面的例子中,创建car1和car2对象时,通过构造方法直接为color、brand、model和displacement属性赋值,相比创建对象后再修改属性更加高效。

3.3 带有默认参数的构造方法​

在构造方法中,可以为参数设置默认值,这样在创建对象时,如果不需要修改该参数的值,就可以不传递该参数。

class Car:category = "交通工具"def __init__(self, color="白色", brand="未知品牌", model="未知型号", displacement=1.5):self.color = colorself.brand = brandself.model = modelself.displacement = displacementdef get_info(self):return f"汽车信息:颜色-{self.color},品牌-{self.brand},型号-{self.model},排量-{self.displacement}T"# 创建对象时不传递所有参数,使用默认值
car3 = Car()
print(car3.get_info())  # 输出:汽车信息:颜色-白色,品牌-未知品牌,型号-未知型号,排量-1.5T# 创建对象时传递部分参数
car4 = Car("蓝色", "丰田")
print(car4.get_info())  # 输出:汽车信息:颜色-蓝色,品牌-丰田,型号-未知型号,排量-1.5T

四、类的属性和方法分类​

4.1 属性分类​

属性类型​定义位置访问方式​特点​举例​
实例属性__init__方法中或对象中​​对象、属性名​每个对象的属性值可以不同,属于对象私有​self.color = color​
类属性​类中,__init__方法外​类名、属性名 或 对象、属性名​所有对象共享该属性值,属于类共有​class Car: wheels = 4(所有汽车都有 4 个轮子)​

举例:​

class Car:​wheels = 4  # 类属性,所有汽车都有4个轮子​def __init__(self, color, brand):​self.color = color  # 实例属性​self.brand = brand  # 实例属性​
​
car1 = Car("红色", "特斯拉")​
car2 = Car("黑色", "宝马")​
​
print(Car.wheels)  # 输出:4​
print(car1.wheels)  # 输出:4​
print(car2.color)  # 输出:黑色​
print(car1.brand)  # 输出:特斯拉​

4.2 方法分类​

方法类型​定义方式​调用方式​特点​举例​
实例方法​def 方法名(self, 参数…):​对象、方法名 ()​依赖于对象,能访问实例属性和类属性​前面例子中的drive()、brake()​
类方法​@classmethod
def 方法名(cls, 参数…):​
类名、方法名 () 或 对象、方法名 ()​依赖于类,能访问类属性,不能直接访问实例属性​用于操作类属性的方法​
静态方法​@staticmethod
def 方法名(参数…):​
类名、方法名 () 或 对象、方法名 ()​不依赖于类和对象,不能直接访问类属性和实例属性​与类相关的工具函数​

举例:​

class Car:wheels = 4  # 类属性def __init__(self, brand):self.brand = brand  # 实例属性# 实例方法def get_brand(self):return self.brand# 类方法@classmethoddef change_wheels(cls, num):cls.wheels = num# 静态方法@staticmethoddef is_car(vehicle):return isinstance(vehicle, Car)car1 = Car("特斯拉")# 调用实例方法
print(car1.get_brand())  # 输出:特斯拉# 调用类方法
Car.change_wheels(6)
print(Car.wheels)  # 输出:6# 调用静态方法
print(Car.is_car(car1))  # 输出:True
print(Car.is_car("不是汽车"))  # 输出:False

五、继承​

继承是面向对象编程的重要特性,它允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的复用。子类可以在父类的基础上添加新的属性和方法,或重写父类的方法。​

5.1 单继承​

子类只继承一个父类。​

语法:​

class 子类名(父类名):# 子类的属性和方法​pass

举例:​

class Vehicle:def __init__(self, color):​self.color = color​​def move(self):print(f"{self.color}的交通工具在移动")​
​
# 子类:汽车,继承自交通工具​
class Car(Vehicle):def __init__(self, color, brand):# 调用父类的构造方法​super().__init__(color)​self.brand = brand​​# 重写父类的move方法​def move(self):print(f"{self.color}{self.brand}汽车在公路上行驶")​
​
car = Car("红色", "特斯拉")​
car.move()  # 输出:红色的特斯拉汽车在公路上行驶​

5.2 多继承​

子类可以继承多个父类。​

语法:

class 子类名(父类名1, 父类名2, ...):# 子类的属性和方法​pass

​举例:​

class Flyable:​def fly(self):​print("可以飞行")​
​
class Swimmable:​def swim(self):​print("可以游泳")​
​
# 子类:水陆空三栖车,继承自Flyable和Swimmable​
class AmphibiousCar(Flyable, Swimmable):​pass​
​
car = AmphibiousCar()​
car.fly()  # 输出:可以飞行​
car.swim()  # 输出:可以游泳​


继承关系示意图:​

继承关系示意图


六、封装与访问控制​

封装是指将对象的属性和方法隐藏起来,只提供有限的接口供外部访问,从而保证数据的安全性。在 Python 中,通过命名约定来实现访问控制。​

  • 公有属性和方法:默认情况下,属性和方法都是公有的,可以通过对象直接访问。​
  • 私有属性和方法:在属性或方法名前加上两个下划线__,私有属性和方法只能在类的内部访问,外部不能直接访问。​

举例:​

class Person:​def __init__(self, name, age):​self.name = name  # 公有属性​self.__age = age  # 私有属性​​def get_age(self):  # 公有方法,用于获取私有属性​return self.__age​​def __secret(self):  # 私有方法​print("这是一个秘密")​
​
person = Person("张三", 25)​
print(person.name)  # 输出:张三​
print(person.get_age())  # 输出:25​
# print(person.__age)  # 报错,不能直接访问私有属性​
# person.__secret()  # 报错,不能直接调用私有方法​

七、多态​

多态是指不同的对象对同一方法调用做出不同的响应。在继承的基础上,子类重写父类的方法,当调用该方法时,会根据对象的实际类型执行相应的方法。​

举例:​

class Animal:def make_sound(self):passclass Dog(Animal):def make_sound(self):print("汪汪汪")class Cat(Animal):def make_sound(self):print("喵喵喵")def animal_sound(animal):animal.make_sound()dog = Dog()
cat = Cat()animal_sound(dog)  # 输出:汪汪汪
animal_sound(cat)  # 输出:喵喵喵

在上面的例子中,Dog和Cat都继承自Animal,并重写了make_sound方法。当调用animal_sound函数时,传入不同的动物对象,会执行不同的make_sound方法,体现了多态的特性。​


总结​

  • Python 面向对象编程通过类、对象、继承、封装和多态等特性,提供了一种灵活、高效的代码组织方式。类是对象的模板,对象是类的实例;继承实现了代码复用;封装保证了数据安全;多态提高了代码的灵活性。​
  • 掌握面向对象编程思想,能够帮助我们设计出更清晰、更易于维护和扩展的程序,尤其在开发大型项目时,优势更为明显。通过不断实践,我们可以更好地理解和运用这些特性,编写出高质量的 Python 代码。​
http://www.xdnf.cn/news/18218.html

相关文章:

  • Golang database/sql 包深度解析(二):连接池实现原理
  • 【前端面试题】前端面试知识点(第三十一题到第六十一题)
  • 《设计模式》抽象工厂模式
  • 24. 什么是不可变对象,好处是什么
  • 适用监测农作物长势和病虫害的高光谱/多光谱相机有哪些?
  • 【网络通信】TCP/IP 协议全方位解析​
  • 【LeetCode】12. 整数转罗马数字
  • STM32——软硬件I2C
  • 8月17日星期天今日早报简报微语报早读
  • 解锁Java开发神器:XXL-Job从入门到精通
  • java如何使用正则提取字符串中的内容
  • Go语言实战案例-使用ORM框架 GORM 入门
  • Centos 更新/修改宝塔版本
  • GaussDB 数据库架构师修炼(十三)安全管理(5)-全密态数据库
  • 【架构师从入门到进阶】第五章:DNSCDN网关优化思路——第十二节:网关安全-信息过滤
  • 哈希表与unorder_set,unorder_map的学习
  • 【Linux系列】常见查看服务器 IP 的方法
  • 深入了解 Filesystem Hierarchy Standard (FHS) 3.0 规范
  • 17.5 展示购物车缩略信息
  • 【Linux】文件基础IO
  • Google Earth Engine | (GEE)逐月下载的MODIS叶面积指数LAI
  • Rust 入门 生命周期(十八)
  • 【牛客刷题】字符串按索引二进制1个数奇偶性转换大小写
  • C#高级语法_委托
  • java基础(十)sql的mvcc
  • 字节 Golang 大模型应用开发框架 Eino简介
  • 进程互斥的硬件实现方法
  • 私人AI搜索新突破:3步本地部署Dify+Ollama+QwQ,搜索能力MAX
  • 《动手学深度学习v2》学习笔记 | 1. 引言
  • Nacos 注册中心学习笔记