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

【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.lryc.cn/news/623604.html

相关文章:

  • 多线程—飞机大战(加入播放音乐功能版本)
  • macos 安装nodepad++ (教程+安装包+报错后的解决方法)
  • Sentinel和12.5米高程的QGIS 3D效果
  • scikit-learn/sklearn学习|套索回归Lasso解读
  • scikit-learn RandomizedSearchCV 使用方法详解
  • scikit-learn 中的均方误差 (MSE) 和 R² 评分指标
  • .NET 中的延迟初始化:Lazy<T> 与LazyInitializer
  • 『搞笑名称生成器』c++小游戏
  • Spring Cloud整合Eureka、ZooKeeper、原理分析
  • 云计算-k8s实战指南:从 ServiceMesh 服务网格、流量管理、limitrange管理、亲和性、环境变量到RBAC管理全流程
  • 【Kubernetes系列】Kubernetes中的resources
  • 脉冲计数实现
  • vue3 ref和reactive的区别和使用场景
  • Nightingale源码Linux进行跨平台编译
  • 数学建模 15 逻辑回归与随机森林
  • 大模型微调【2】之使用AutoDL进行模型微调入门
  • 工具测试 - marker (Convert PDF to markdown + JSON quickly with high accuracy)
  • 深入理解 uni-app 页面导航:switchTab、navigateTo、redirectTo、reLaunch 与 navigateBack
  • 回溯剪枝的 “减法艺术”:化解超时危机的 “救命稻草”(一)
  • 基于径向基函数神经网络的数据回归预测 RBF
  • 【Jenkins】02 - 自动化部署配置
  • Matlab数字图像处理——梯度稀疏性和泊松方程求解的反光/倒影去除系统
  • C#中List、Path、字符串操作等常用方法总结
  • Git登录配置的详细方法
  • Python入门第7课:异常处理机制:让你的程序更健壮(try-except详解)
  • uniapp中uni.showToast和 uni.showLoading同时使用时出现提示中断冲突问题。
  • 《告别 if-else 迷宫:Python 策略模式 (Strategy Pattern) 的优雅之道》
  • 【Tech Arch】Hive技术解析:大数据仓库的SQL桥梁
  • 在 Element UI 的 el-table 中实现某行标红并显示删除线
  • Java 大视界 -- 基于 Java 的大数据分布式计算在气象灾害预警与应急响应中的应用