目录
[4.2、init( )](#4.2、init( ))
[4.3、str( )](#4.3、str( ))
[4.4、del( )](#4.4、del( ))
1、什么是面向对象
1.1、面向对象和面向过程
编程思想就是人们利用计算机来解决问题的思维。
常见的思维方式有面向过程和面向对象。python是同时支持面向过程 和面向对象的编程语言。
分类
1.面向过程
它是一种编程思想, 强调的是以 步骤(过程) 为基础完成各种操作。
2.面向对象
它是一种编程思想, 强调的是以 对象 为基础完成各种操作, 它是基于面向过程的。使人们的编程与实际的世界更加接近,所有的对象被赋予属性(名词) 和方法(动词) ,这样编程就更加富有人性化。宗旨在于模拟现实世界。在现实生活中,所有事物全被视为对象(万物皆对象)。
- 更符合人们的思考习惯
- 把复杂的事情简单化
- 把人们从执行者变为指挥者
1.2、面向对象特征介绍
对于面向对象,通常具有以下这三大特性:
- 封装:把属性和方法封装在一起,仅提供对外的方法让别人去访问。好处: 简化编程
- 继承:孩子可使用老爹的东西。好处:代码复用
- 多态 :同样一个函数(消息)在不同场景下表现出不同形态。 好处:解耦合,可拓展(一象多用)
1、封装
在面向对象中,封装就是隐藏对象的属性和实现细节,仅对外公开接口 ,控制在程序中属性的读和修改的访问级别,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成**"类"**,其中数据和函数都是类的成员。
- 封装的目的是简化编程,增强安全性
- 使用者不必了解具体的实现细节,而只是要通过外部接口以特定的访问权限来使用类的成员。
2、继承
在现实生活中,继承一般指的是子女继承父辈的财产,如"子承父业" 等;在面向对象中,继承也是面向对象的基本特征之一;继承就是子类继承父类的属性和方法,使得子类对象(实例)具有父类的特征和行为。
3、多态
多态是指不同类的对象对同一消息做出响应,即同一消息可根据发送对象的不同而采用多种不同的行为方式。同样一个函数(消息)在不同场景下表现出不同形态(功能)
2、面向对象的基本概念
2.1、类与对象
Python是一门面向对象的语言(也是一门面向过程的语言)。要掌握面向对象的基本语法,则首先需要掌握两个重要的概念:
- **类:**抽象的模板,对现实事物的抽象描述
- **对象:**具体的实体,现实事物的具体体现
面向对象核心概念:
类: 抽象的概念, 看不见, 摸不着, 是 属性(名词) 和 行为(动词)的集合.
对象: 类的具体体现, 实现.
**属性(名词):**用来描述事物的外在特征的, 例如: 姓名, 年龄...
格式: 和以前定义变量一样.
**方法(动词):**用来描述事物能够做什么的, 例如: 吃, 喝...
格式: 和以前定义函数一样.
类是对事物的抽象,对象是对现实事物的具体体现。
2.2、创建类
我们都知道汽车是由汽车图纸生产出来 的,那么汽车图纸 就是一个模板(即类) ,在汽车图纸上,指定规则:生产出来的汽车必须具有跑起来 的行为。这是抽象的概念模型。
类的基本语法格式
python# 定义类 class 类名: # 定义方法 方法列表...案例:定义一个汽车类,并具有跑起来的行为
python# 1.定义汽车类. class Car: # 类名遵循 大驼峰命名法. # 属性 # 方法 def run(self): print('汽车会跑!...')
2.3、创建对象与调用
如何访问类中的成员?
- 创建该类的对象.
python对象名 = 类名()
- 通过 对象名. 的方式调用.
python对象性.属性名 对象名.方法名()案例:
python# 1.定义汽车类. class Car: # 属性 # 方法 def run(self): print('汽车会跑!...') # 2.创建汽车类的对象. c1 = Car() # 3. 调用Car类的run()函数, 简写版: 调用Car#run() c1.run()
2.4、self关键字
概述:
- self 是Python内置的关键字, 用于表示本类当前对象的引用, 指向对象实例本身。
作用:
- 1个类是可以有多个对象的, 这多个对象都可以通过 **对象名.**的方式访问类中的行为(函数)
- 函数默认有self属性, 函数通过self来区分到底是哪个对象调用的该函数。
案例1
定义汽车类, 创建多个该类的对象, 看看打印结果。
python# 1. 定义汽车类. class Car: # 属性 # 方法, 跑 def run(self): print('汽车会跑!...') print(f'我是run函数, self的值是: {self}') # 2.创建汽车类的对象. c1 = Car() print(f'c1对象: {c1}') # 通过 对象名. 的形式, 调用Car#run() c1.run() print('-' * 36) # 3.继续创建汽车类的对象. c2 = Car() print(f'c2对象: {c2}') # 通过 对象名. 的形式, 调用Car#run() c2.run()根据输出结果可以发现self和当前对象相同, 谁调用函数, self就代表哪个对象。
案例2
定义汽车类, 类内有run()函数, 并在work()中调用run()函数, 创建该类对象, 调用上述的函数.
python# 1. 定义汽车类. class Car: # 属性(名词) # 方法(动词) # 1.1 run()函数 def run(self): print(f'{self} 汽车在跑...') # 1.2 work()函数, 在其内部调用run() def work(self): print(f'我是work函数, 我的self值: {self}') self.run() # self = 本类当前对象的引用. # 2.在类外访问Car类的方法(函数) c1 = Car() print(f'c1对象: {c1}') c1.run() # c1在跑 print('-' * 36) c1.work() # c1在work, c1在跑 print('*' * 36) # 分割线 # 3.再次创建对象. c2 = Car() print(f'c2对象: {c2}') c2.run() print('-' * 36) c2.work()总结:
- 在类外 访问类中的方法, 需要通过 对象名. 的方式访问。
- 在类内 访问类中的方法,需要通过**self.**的方式访问。
案例3
定义手机类, 能开机, 关机, 拍照。
python# 1.定义手机类. class Phone: # 属性 # 方法 # 1.1 开机. def open(self): print(f'{self} 手机开机了') # 1.2 关机. def close(self): print(f'{self} 手机关机了') # 1.3 拍照. def take_photo(self): print(f'{self} 手机拍照了') # 2. 创建手机类对象, 访问其成员. p1 = Phone() print(f'p1对象: {p1}') p1.open() p1.take_photo() p1.close() print('-' * 36) # 3.继续创建手机类对象, 访问其成员. p2 = Phone() print(f'p2对象: {p2}') p2.open() p2.take_photo() p2.close()
3、添加和获取对象属性
3.1、属性
属性表示的是固有特征 ,在Python中使用变量表示,例如人的姓名、年龄、身高、体重等,都是对象的属性。
3.2、类外面添加和获取对象属性
类外, 设置对象的属性, 格式如下:
特点: 该属性独属于这个对象, 即: 该类的其它对象没有这个属性。
类外, 获取对象的属性, 格式如下:
python对象名.属性名案例:
创建汽车类, 设置为红色, 4个轮胎, 有跑的功能。
python# 1.创建汽车类. class Car: # 属性(名词), 事物具有哪些特征 -> 变量. # 行为(动词), 事物能够做什么 -> 函数. def run(self): print('汽车会跑...') # pass # 2.创建该类的对象 -> 这个是 类外 的位置. c1 = Car() c1.run() # 汽车会跑... # 细节1: 给c1对象设置属性. c1.color = '红色' c1.number = 4 # 细节2: 打印c1对象的属性值. print(f'颜色: {c1.color}, 轮胎数: {c1.number}') print('-' * 36) # 3.继续创建该类的对象. c2 = Car() c2.run() # 细节3: 尝试调用c2对象的 color和number属性 # print(f'颜色: {c2.color}, 轮胎数: {c2.number}')
3.3、类内部获取对象属性
回顾:
类外访问类中的成员, 可以通过**对象名.**的方式.
类内访问类中的成员, 可以通过 **self.**的方式.
类外通过 对象名.属性名 = 属性值的方式 设置属性, 只有当前对象有.
细节:
类内如何设置属性, 要结合 魔法方法**init( )**来实现, 在后面的魔术方法中介绍。
案例:
定义汽车类, 创建该类对象, 赋予颜色 和 轮胎数两个属性, 并在类内访问该属性。
python# 1. 定义汽车类 class Car: # 属性 # 行为 # 1.1 跑 def run(self): print('汽车会跑') # 1.2 定义函数show(), 实现 在类内访问 汽车对象的属性. def show(self): print(f'我是show函数, 对象的颜色: {self.color}, 轮胎数: {self.number}') # 2.创建汽车类的对象 c1 = Car() # 3. 给其(c1)赋予 属性 -> 类外设置属性. c1.color = '红色' c1.number = 4 # 4. 类外访问属性. print(f"颜色: {c1.color}, 轮胎数: {c1.number}") # 5. 类外访问行为(类中的函数) c1.run() c1.show() print('-' * 36) # 6. 继续创建汽车类对象, 尝试分别调用run(), show()函数. c2 = Car() c2.run() # c2.show() # 报错.
4、魔法方法
4.1、概念
在Python中,有一些可以给Python类增加魔力的特殊方法 ,它们总是被双下划线所包围 ,我们称之为魔法方法。在特殊情况下会被自动调用,不需要开发者手动去调用。
python__魔术方法名__()
4.2、init( )
在Python中,当新创建一个对象时,则会自动触发__init__( )魔法方法。
分为两种情况:
- 无参数情况:不需要外面传递参数,初始化属性值。
- 有参数情况:当需要外面传递参数,初始化属性值。
无参数情况
案例:
定义汽车类, 默认属性为: color='黑色', number=3。
python# 1. 定义汽车类. class Car: # 1.1 在魔法方法 init()中, 初始化: 属性. def __init__(self): print('我是 无参 init 魔法方法') # 1.2 在init魔法方法中, 初始化属性, 则: 该类所有的对象, 一创建, 就有这些属性了. self.color = '黑色' self.number = 3 # 1.3 定义show()函数, 打印该类对象的 各个属性值. def show(self): print(f'颜色: {self.color}, 轮胎数: {self.number}') # 2.创建汽车类对象. c1 = Car() # 会自动调用 __init__()函数. # 修改c1的属性值 c1.color = '红色' c1.number = 6 # 打印c1对象的属性值. print(c1.color, c1.number) c1.show() print('-' * 36) c2 = Car() c2.show()
有参数情况
案例:
创建汽车类, 不给默认值, 由汽车对象 外部各自赋值即可。
python# 1. 定义汽车类. class Car: # 2.有参的 __init__()函数, 参数值由: 外部对象自行赋值. def __init__(self, color, number): """ 该魔法方法用于给 汽车类 对象的属性 赋值. :param color: 车的颜色 :param number: 车的轮胎数 """ self.color = color self.number = number # 定义show()函数, 打印该类对象的 各个属性值. def show(self): print(f'颜色: {self.color}, 轮胎数: {self.number}') # 3. 创建汽车类对象. # c1 = Car() # 报错, 因为默认调用了init()函数, 但是该函数有参数, 则必须传参. c1 = Car('红色', 6) c1.show() print('-' * 36) c2 = Car('绿色', 4) c2.show() c3 = Car()
4.3、str( )
当使用print输出对象时,默认打印对象的内存地址 ;如实现了__str__( )方法,print就自动调用该魔法方法,返回的值必须为字符串。
案例:
python# 1. 定义汽车类. class Car: # 2.有参的 __init__()函数, 参数值由: 外部对象自行赋值. def __init__(self, color, number): """ 该魔法方法用于给 汽车类 对象的属性 赋值. :param color: 车的颜色 :param number: 车的轮胎数 """ self.color = color self.number = number # 魔法方法str(), 默认打印地址值, 无意义, 一般会重写, 改为打印对象的各个属性值. def __str__(self): # 返回值必须是字符串 return f'颜色: {self.color}, 轮胎数: {self.number}' # return f'{self.color}, {self.number}' # 3.创建该类的对象. c1 = Car('绿色', 4) print(c1) # 输出语句打印对象, 默认调用了该对象 所在类的 str魔法方法. print('-' * 36) c2 = Car('红色', 6) print(c2)
4.4、del( )
当删除对象时(调用del删除对象或文件执行结束后),Python解释器会默认调用__del__( )方法。
案例:
python# 1. 定义汽车类, 属性: 品牌. 行为:run() 通过del魔法方法删除该类的对象, 看看效果. class Car: # 2. 在魔法方法init中, 完成: 属性的初始化. def __init__(self, brand): self.brand = brand # 3.重写 str魔法方法, 打印对象的属性值. def __str__(self): return f'品牌: {self.brand}' # 4. 重写 del魔法方法, 删除对象时给出提示. def __del__(self): print(f'{self} 对象被删除了!') # 5. 创建汽车类对象. c1 = Car('小米 Su7 Ultra') print(c1) # 6. 手动访问 brand 属性. print(c1.brand) print('-' * 36) # 7.手动删除c1对象, 然后尝试 打印该对象 或者 访问对象的属性. # del c1 # print(c1) # 报错. print('程序结束!')
5、面向对象的综合案例
5.1、案例1
python""" 案例: 减肥案例. 需求: 例如,小明同学当前体重是100kg。每当他跑步一次时,则会减少0.5kg;每当他大吃大喝一次时,则会增加2kg。请试着采用面向对象方式完成案例。 分析: 类名: Student 对象名: xm 属性(名词): 当前体重, current_weight 行为(动词) 跑步, 吃饭 """ # 1.定义学生类. class Student: # 2.在魔法方法init中, 完成: 对象的属性的初始化. def __init__(self): self.current_weight = 100 # 3.每当他跑步一次时,则会减少0.5kg def run(self): print('疯狂跑步...') self.current_weight -= 0.5 # 体重减小. # 4.大吃大喝. def eat(self): print('大吃大喝一顿...') self.current_weight += 2 # 5.重写魔法方法str, 打印属性值, 即: 当前体重. def __str__(self): # return '当前体重: %s' % self.current_weight return f'当前体重: {self.current_weight} kg!' # 6. 测试. if __name__ == '__main__': # 6.1 创建学生对象. xm = Student() # 6.2 跑步 xm.run() xm.run() # 6.3 吃喝 xm.eat() # 6.4 当前体重. print(xm)
5.2、案例2
python""" 案例: 烤地瓜案例. 需求: 1. 定义地瓜类 -> SweetPotato 2. 属性: 被烤时间cook_time, 烘焙状态 cook_state, 调料 condiments 3. 行为: 烘烤cook(), 添加调料 add_condiment() 4. 魔法方法: init() -> 初始化属性, str() -> 打印地瓜信息. 5. 规则: 烘烤时间 地瓜状态 [0, 3) 生的 包左不包右, 前闭后开. [3, 7) 半生不熟 [7, 12) 熟了 [12, ∞] 糊了 """ # 1. 定义地瓜类 -> SweetPotato class SweetPotato: # 2. 在魔法方法__init__()中, 初始化地瓜的属性. def __init__(self): self.cook_time = 0 self.cook_state = '生的' self.condiments = [] # 3.具体的烘烤动作. def cook(self, time): # 3.1 根据烘烤时间, 修改地瓜的烘烤状态. if time < 0: print('无效值!') else: # 3.2 修改地瓜的 烘烤时间. self.cook_time += time # 3.3 根据烘烤时间, 修改地瓜的烘烤状态. if 0 <= self.cook_time < 3: self.cook_state = '生的' elif 3 <= self.cook_time < 7: self.cook_state = '半生不熟' elif 7 <= self.cook_time < 12: self.cook_state = '熟了' else: self.cook_state = '糊了' # 4. 添加调料 add_condiment() def add_condiment(self, condiment): self.condiments.append(condiment) # 5. 重写str()方法, 打印地瓜信息. def __str__(self): return f'烘烤时间: {self.cook_time}, 地瓜状态: {self.cook_state}, 调料: {self.condiments}' # 6.测试. if __name__ == '__main__': # 7. 创建地瓜对象 dg = SweetPotato() # 8. 具体的烘烤动作. # dg.cook(-3) dg.cook(3) dg.cook(5) dg.cook(7) # 9. 添加调料 dg.add_condiment('芥末/辣根') dg.add_condiment('折耳根') dg.add_condiment('豆汁') dg.add_condiment('鲱鱼罐头') # 10. 打印地瓜状态. print(dg)









