面向对象基础
前言
- 前面我们学习的Python的入门知识都是基于面向过程的思想,我们解决问题的时候,会把所需要的步骤都列出来,然后按照步骤写代码挨个实现,这种过程化的叙事思维,就是我们的视角不再是步骤过程,而是另一个视角:操作完整对象。。
- 接下来我们将学习面向对象的思想,我们的视角不再是步骤过程,而是另一个视角:操作完整对象。
一、面向对象的三大特性(下个文章详解)
- 封装:把属性和方法封装到类中进行隐藏,对外提供访问接口
- 继承:子承父业 子类继承父类的属性和方法
- 多态:同样一个函数在不同的场景下有不同的表现 (多种状态)
二、面向对象的基本概念
2.1. 类
- 对现实事物的抽象描述
- 即对一类物体的统称
格式
"""
创建类的三种方式:
1、class 类名:
2、class 类名():
3、class 类名(object):
class 类名:
# 定义方法
方法列表...
"""
代码如下(示例):
# 定义类:class 类名:
class Car:
# 2.定义方法:跑起来
def run(self):
print('能跑起来...')
2.2. 对象
- 对象:现实事物的具体体现
- 即一类事物中的具体的事物
格式
"""
对象名 = 类名() # 创建对象
"""
代码如下(示例):
# 1.定义类:class 类名:
class Car:
# 1.1.定义方法:跑起来
def run(self):
print('能跑起来...')
# 2.创建对象:对象名 = 类名()
car = Car()
# 3.调用方法:对象.方法名()
car.run()
2.3. 综合案例
代码如下(示例):
# 需求: 定义1个汽车类, 然后具有跑的功能, 并调用.
# 1. 定义汽车类.
class Car():
# 属性, 先不写.
# 行为, 和以前定义的函数一样, 只不过第一个形参要写self.
def run(self):
print('汽车会跑!...')
# 在main方法中测试调用.
if __name__ == '__main__':
# 2. 创建汽车类对象.
c1 = Car() # 大白话: 根据图纸制造了1辆汽车, 汽车名叫: c1
c2 = Car() # 大白话: 根据图纸制造了1辆汽车, 汽车名叫: c2
# 3. 调用 汽车类的 功能.md
# 3.1 调用 属性
# 3.2 调用 行为.
c1.run()
c2.run()
# 4. 直接打印c1, c2 看看是什么.
print(f'c1: {c1}') # 地址值: <__main__.Car object at 0x0000026F32BDC260>
print(f'c2: {c2}') # 地址值: <__main__.Car object at 0x0000026F32BDC290>
2.4. self 关键字
介绍
"""
1、概述:
它是Python内置的一个属性, 代表: 本类当前对象的引用.
大白话:
谁(哪个对象)调用函数, 函数内的self就代表谁(对象).
谁调用, self就是谁.
2、作用:
用于函数内, 区分不同对象的, 因为: 汽车类的run()函数, c1对象能调用, c2对象也能调用.
run()函数内部就可以通过 self来区分到底是c1 还是 c2调用了该函数.
"""
代码如下(示例):
# 需求: 定义汽车类, 有run()的功能, 然后创建该类的对象, 并调用run()功能. 细节: run()要区分是哪个对象调用的.
# 1. 定义汽车类.
class Car:
# 汽车类内部, 定义: 行为(函数), 表示具有: 跑的功能.
def run(self):
print('汽车具有 跑 的功能!')
# 通过self关键字, 可以实现: 在函数内区分 到底是哪个对象 调用的该函数.
print(f'当前对象为: {self}')
# 在main函数中, 测试调用.
if __name__ == '__main__':
# 2. 创建汽车类的对象.
c1 = Car()
c2 = Car()
# 3. 调用Car类的 run()函数, 简写注释为: 调用 Car#run()
c1.run() # 汽车具有 跑 的功能! 当前对象为: <__main__.Car object at 0x00000200D727B800>
print('-' * 21)
c2.run() # 汽车具有 跑 的功能! 当前对象为: <__main__.Car object at 0x00000200D727B830>
print('-' * 21)
# 4. 打印地址值.
print(f'c1: {c1}') # c1: <__main__.Car object at 0x00000200D727B800>
print(f'c2: {c2}') # c2: <__main__.Car object at 0x00000200D727B830>
代码如下(示例):
"""
案例: 在类内部调用类中的函数.
调用函数的格式介绍:
类外: 对象名. 的方式调用.
类内: self. 的方式调用.
回顾:
函数内有self, 表示: 谁调用这个函数, self就是哪个对象.
简单理解: self = 本类的对象.
"""
# 需求: 定义汽车类, 有跑的功能run(), 然后分别在 类内, 类外调用 run()函数.
# 1. 定义汽车类.
class Car:
# 定义函数, 表示: 跑的功能.
def run(self):
print('汽车会跑!...')
# 2. 测试在类中访问本类的函数.
def work(self):
# 2.1 打印1句话, 提示用.
print('我是 work() 函数!')
# 2.2 调用 run()函数.
self.run()
# 在main函数中测试.
if __name__ == '__main__':
# 3. 测试在 类外 访问 类的函数.
# 3.1 创建汽车类对象
c1 = Car()
# 3.2 调用汽车类, 跑的功能.
c1.run()
print('-' * 21)
# 4. 调用work()函数.
c1.work()
三、添加和获取对象属性
属性表示的是固有特征,在Python中使用变量表示,例如人的姓名、年龄、身高、体重等,都是对象的属性。
代码如下(示例):
"""
1、概述:
属性 = 名词, 即: 描述事物的外在特征的. 例如: 姓名, 年龄, 性别...
2、格式:
类外: 对象名.属性名 = 属性值
类内: 要结合 __init__() 魔法方法一起使用.
3、调用属性的格式:
类外: 对象名.属性名
类内: self.属性名
"""
代码如下(示例):
# 需求: 给车设置颜色为红色, 4个轮胎, 且获取属性值并输出.
# 扩展: 可以在类内部定义1个show()方法来获取刚才给车设置的属性.
# 1. 定义汽车类.
class Car:
# 2. 在类内定义show()方法, 获取属性值. 即: 类内获取属性值
def show(self):
# self = 本类当前对象的引用.
print(f'颜色: {self.color}, 轮胎数: {self.num}')
# 在main函数中测试调用.
if __name__ == '__main__':
# 3. 创建对象.
c1 = Car()
# 4. 给c1对象设置属性值. 类外设置属性
c1.color = '红色'
c1.num = 4
# 5. 打印c1对象的属性值. 类外获取属性值.
print(f'颜色: {c1.color}, 轮胎数: {c1.num}') # 颜色: 红色, 轮胎数: 4
# 6. 调用show()方法, 获取属性值.
c1.show() # 颜色: 红色, 轮胎数: 4
四、魔法方法
- 在Python中,有一些可以给Python类增加魔力的特殊方法,我们称之为魔法方法。在特殊情况下会被自动调用。
4.1 __ init __() 方法
在Python中,当新创建一个对象时,则会自动触发__init__()魔法方法。
4.1.1 无参数的 __ init __() 方法
- 不需要外面传递参数,初始化属性值
代码如下(示例):
# 需求: 给车这个对象默认设置 颜色 color=黑色, 轮胎数 number=3
# 1. 定义汽车类.
class Car():
# 2. 通过 魔法方法 init, 初始化 汽车对象的属性值, 即: 所有汽车类对象, 默认都有这个属性值.
def __init__(self): # 无参数的 init函数.
print('我是init函数, 我被调用了!')
# 具体的设置属性值的动作.
self.color = '黑色'
self.number = 3
# 3. 定义函数show(), 在类内调用 属性.
def show(self):
print(f'颜色: {self.color}, 轮胎数: {self.number}')
# 在main函数中测试.
if __name__ == '__main__':
# 4. 创建汽车类对象.
c1 = Car()
c2 = Car()
print('-' * 21)
# 扩展: 修改c1的属性值.
c1.color = '霞光紫'
c1.number = 10
# # 5. 调用show()函数, 打印属性值.
c1.show()
print('-' * 21)
c2.show()
print('-' * 21)
# 6. 扩展, 在类外调用属性.
print(c1.color, c1.number)
print(c2.color, c2.number)
打印结果
我是init函数, 我被调用了!
我是init函数, 我被调用了!
---------------------
颜色: 霞光紫, 轮胎数: 10
---------------------
颜色: 黑色, 轮胎数: 3
---------------------
霞光紫 10
黑色 3
4.1.1 有参数的 __ init __() 方法
代码如下(示例):
# 需求: 通过外部传参的方式, 给汽车对象设置属性值, 例如: 褐色, 6个轮胎.
# 1. 定义汽车类.
class Car():
# 2. 通过 魔法方法 init, 初始化 汽车对象的属性值, 即: 所有汽车类对象, 默认都有这个属性值.
def __init__(self, color, number): # 带参数的 init函数.
# def __init__(self, color = None, number = None): # 带参数的 init函数.
print('我是init函数, 我被调用了!')
# 具体的设置属性值的动作.
self.color = color
self.number = number
# 3. 定义函数show(), 在类内调用 属性.
def show(self):
print(f'颜色: {self.color}, 轮胎数: {self.number}')
# 在main函数中测试.
if __name__ == '__main__':
# 4. 创建汽车类对象.
c1 = Car('黑色', 6) # 因为__init__函数带参, 所以需要传参.
c2 = Car('红色', 10)
print('-' * 21)
# 扩展: 修改c1的属性值.
c1.color = '霞光紫'
c1.number = 10
# # 5. 调用show()函数, 打印属性值.
c1.show()
print('-' * 21)
c2.show()
print('-' * 21)
# 6. 扩展, 在类外调用属性.
print(c1.color, c1.number)
print(c2.color, c2.number)
打印结果
我是init函数, 我被调用了!
我是init函数, 我被调用了!
---------------------
颜色: 霞光紫, 轮胎数: 10
---------------------
颜色: 红色, 轮胎数: 10
---------------------
霞光紫 10
红色 10
4.2 __ str __() 方法
__str__() 当输出语句直接打印对象的时候, 会自动调用该魔法方法, 默认打印的是地址值, 无意义, 一般会改为: 打印该对象的各个属性值.
代码如下(示例):
# 1. 定义汽车类, 属性: 品牌, 价格.
class Car():
# 定义init, 初始化属性.
def __init__(self, brand, price):
self.brand = brand # 品牌
self.price = price # 价格
# 行为
def run(self):
print('汽车会跑!')
# 魔法方法, str
def __str__(self):
# return '我是str魔法方法'
return f'品牌: {self.brand}, 价格: {self.price}'
# 魔法方法, del
def __del__(self):
print(f'对象 {self} 被删除了!')
# 在main函数中测试调用.
if __name__ == '__main__':
# 2. 创建汽车类对象.
c1 = Car('小米Su7', 239999) # 创建对象时, 自动调用了: init魔法方法
# 3. 直接打印c1对象
print(c1) # 默认调用了 __str__() 魔法方法.
# 4. 删除c1对象, 看看结果.
# del c1
打印结果
品牌: 小米Su7, 价格: 239999
对象 品牌: 小米Su7, 价格: 239999 被删除了!
4.3 __ del __() 方法
__del__() 当手动删除对象时 或者 文件执行结束后, 该函数会被自动调用.
代码如下(示例):
# 1. 定义汽车类, 属性: 品牌, 价格.
class Car():
# 定义init, 初始化属性.
def __init__(self, brand, price):
self.brand = brand # 品牌
self.price = price # 价格
# 行为
def run(self):
print('汽车会跑!')
# 魔法方法, str
def __str__(self):
# return '我是str魔法方法'
return f'品牌: {self.brand}, 价格: {self.price}'
# 魔法方法, del
def __del__(self):
print(f'对象 {self} 被删除了!')
# 在main函数中测试调用.
if __name__ == '__main__':
# 2. 创建汽车类对象.
c1 = Car('小米Su7', 239999) # 创建对象时, 自动调用了: init魔法方法
# 3. 直接打印c1对象
# print(c1) # 默认调用了 __str__() 魔法方法.
# 4. 删除c1对象, 看看结果.
del c1
打印结果
对象 品牌: 小米Su7, 价格: 239999 被删除了!
总结
- 以上就是面向对象的基础知识。