目标
在 类的外部,通过 对象名. 访问对象的 属性和方法
在 类封装的方法(函数)中,通过 self. 访问对象的 属性和方法
一、理解面向对象
面向对象编程 —— Object Oriented Programming 简写 OOP
面向对象是一种抽象化的编程思想,很多编程语言中都有的一种思想。
总结:面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么事。
1.1 面向对象基本概念
我们之前学习的编程方式就是 面向过程 的
面相过程 和 面相对象,是两种不同的 编程方式
对比 面向过程 的特点,可以更好地了解什么是 面向对象
1.2 过程和函数(科普)
过程 是早期的一个编程概念
过程 类似于函数,只能执行,但是没有返回值
函数 不仅能执行,还可以返回结果
1.3 面相过程 和 面相对象 基本概念
1.3.1 面相过程 —— 怎么做?
把完成某一个需求的 所有步骤 从头到尾 逐步实现
根据开发需求,将某些 功能独立 的代码 封装 成一个又一个 函数
最后完成的代码,就是顺序地调用 不同的函数
特点
注重 步骤与过程,不注重职责分工
如果需求复杂,代码会变得很复杂
开发复杂项目,没有固定的套路,开发难度很大!
1.3.2 面向对象 —— 谁来做?
相比较函数,面向对象 是 更大 的 封装,根据 职责 在 一个对象中 封装 多个方法
在完成某一个需求前,首先确定 职责 —— 要做的事情(方法)
根据 职责 确定不同的 对象,在 对象 内部封装不同的 方法(多个)
最后完成的代码,就是顺序地让 不同的对象 调用 不同的方法
特点
注重 对象和职责,不同的对象承担不同的职责
更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路
需要在面向过程基础上,再学习一些面向对象的语法
二、类和对象
在面向对象编程过程中,有两个重要组成部分:类 和 对象。
类和对象的关系:
用类去创建一个对象。
用类去实例化一个对象。
2.1 类和对象的关系(重点)
类是模板,对象 是根据 类 这个模板创建出来的,应该 先有类,再有对象
类 只有一个,而 对象 可以有很多个。
不同的对象 之间 属性 可能会各不相同
类 中定义了什么 属性和方法,对象 中就有什么属性和方法,不可能多,也不可能少
2.2 理解类和对象
2.2.1 类
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不能直接使用,不是真实存在的事物。
对象的特征,即是属性
对象的行为(动词),即是方法
类比如是制造洗衣机时要用到的图纸,是一个模板,也就是说类是用来创建对象。
提示:需求中没有涉及的属性或者方法在设计类时,不需要考虑
1)类的设计(类名、属性、方法)
在使用面相对象开发前,应该首先分析需求,确定一下,程序中需要包含哪些类!
在程序开发中,要设计一个类,通常需要满足一下三个要素:
类名 这类事物的名字,满足大驼峰命名法
属性 这类事物具有什么样的特征
方法 这类事物具有什么样的行为
2)大驼峰命名法
每一个单词的首字母大写
单词与单词之间没有下划线
3)类名的确定
名词提炼法 分析 整个业务流程,出现的 名词,通常就是找到的类
2.2.2 对象
对象是类创建出来的真实存在的事物,可以直接使用。例如:洗衣机。
由 哪一个类 创建出来的 对象,就拥有在 哪一个类 中定义的:
属性
方法
注意:程序开发中,先有类,再有对象。
2.3 面向对象实现方法(重点)
2.3.1 定义类
Python2中类分为:经典类 和 新式类
Python2中类分为:经典类 和 新式类
- 语法
class 类名(): def 方法1(self, 参数列表): pass def 方法2(self, 参数列表): pass
- 方法 的定义格式和之前学习过的函数 几乎一样
- 区别在于第一个参数必须是
self
,大家暂时先记住,稍后介绍self
注意:类名要满足标识符命名规则,同时遵循大驼峰命名习惯。
- 体验
class Washer(): def wash(self): print('我会洗衣服')
- 拓展:经典类
不由任意内置类型派生出的类,称之为经典类
class 类名: def 方法1(self, 参数列表): pass def 方法2(self, 参数列表): pass
2.3.2 创建对象(实例)
对象又名实例。
- 当一个类定义完成之后,要使用这个类来创建对象,语法格式如下:
对象名 = 类名()
- 体验
# 创建对象 haier1 = Washer() # <__main__.Washer object at 0x0000018B7B224240> print(haier1) # haier对象调用实例方法 haier1.wash()
注意:创建对象的过程也叫实例化对象。
2.3.3 self对象
self指的是调用该函数的对象。
用这个类创建了一个对象,这个对象拥有这个类当中的所有属性和方法。
# 1. 定义类 class Washer(): def wash(self): print('我会洗衣服') # <__main__.Washer object at 0x0000024BA2B34240> print(self) # 2. 创建对象 haier1 = Washer() # <__main__.Washer object at 0x0000018B7B224240> print(haier1) # haier1对象调用实例方法,将haier1这个对象传入到self中 haier1.wash() haier2 = Washer() # <__main__.Washer object at 0x0000022005857EF0> print(haier2)
注意:打印对象和self得到的结果是一致的,都是当前对象的内存中存储地址。
一个类可以创建多个对象;
多个对象都调用函数的时候,self地址不相同
三、添加和获取对象属性(重点)
属性即是特征,比如:洗衣机的宽度、高度、重量…
对象属性既可以在类外面添加和获取,也能在类里面添加和获取。
3.1 类外面添加对象属性(不推荐)
在 Python 中,要 给对象设置属性,非常的容易,但是不推荐使用
因为:对象属性的封装应该封装在类的内部
- 语法
对象名.属性名 = 值 • 1
- 体验
haier1.width = 500 haier1.height = 800
3.2 类外面获取对象属性
- 语法
对象名.属性名 • 1
- 体验
print(f'haier1洗衣机的宽度是{haier1.width}') print(f'haier1洗衣机的高度是{haier1.height}')
3.3 类里面获取对象属性(使用self)
- 语法
self.属性名
- 体验
# 定义类 class Washer(): def print_info(self): # 类里面获取实例属性 print(f'haier1洗衣机的宽度是{self.width}') print(f'haier1洗衣机的高度是{self.height}') # 创建对象 haier1 = Washer() # 添加实例属性 haier1.width = 500 haier1.height = 800 # 对象调用实例方法 haier1.print_info()
由 哪一个对象 调用的方法,方法内的 self 就是 哪一个对象的引用
在类封装的方法内部,self 就表示 当前调用方法的对象自己
调用方法时,程序员不需要传递 self 参数
在方法内部
可以通过 self. 访问对象的属性
也可以通过 self. 调用其他的对象方法
四、魔法方法
在Python中,__xx__()的函数叫做魔法方法,指的是具有特殊功能的函数。
4.1 dir 内置函数(知道)
在 Python 中 对象几乎是无所不在的,我们之前学习的 变量、数据、函数 都是对象
在 Python 中可以使用以下两个方法验证:
在 标识符 / 数据 后输入一个 .,然后按下 TAB 键,iPython 会提示该对象能够调用的 方法列表
使用内置函数 dir 传入 标识符 / 数据,可以查看对象内的 所有属性及方法
提示 __方法名__ 格式的方法是 Python 提供的 内置方法 / 属性,稍后会给大家介绍一些常用的 内置方法 / 属性
提示 利用好 dir() 函数,在学习时很多内容就不需要死记硬背了
4.2 __init__() 初始化方法(重点)
当使用 对象名=类名() 创建对象时,会 自动 执行以下操作:
为对象在内存中 分配空间 —— 创建对象
为对象的属性 设置初始值 —— 初始化方法(init)
这个 初始化方法 就是 __init__ 方法,__init__ 是对象的内置方法
__init__ 方法是 专门 用来定义一个类 具有哪些属性的方法!
4.2.1 体验__init__()
思考:洗衣机的宽度高度是与生俱来的属性(创建对象之前拥有的属性,在类里面设置),可不可以在生产过程中就赋予这些属性呢?
答:理应如此。
__init__()方法的作用:初始化对象。 该方法在创建对象时会被自动调用
语法
# 1.在 __init__ 方法内部使用,定义属性 self.属性名 = 属性的初始值 # 2.定义属性之后,再使用 类 创建的对象,都会拥有该属性。
class Washer(): # 定义初始化功能的函数 def __init__(self): # 添加实例属性 self.width = 500 self.height = 800 def print_info(self): # 类里面调用实例属性 print(f'洗衣机的宽度是{self.width}, 高度是{self.height}') haier1 = Washer() # 创建对象 haier1.print_info() # 对象调用实例方法
注意:
__init__()
方法,在创建一个对象时默认被调用,不需要手动调用__init__(self)
中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。
4.2.2 带参数的__init__()
(特重点)
思考:一个类可以创建多个对象,如何对不同的对象设置不同的初始化属性呢?
答:传参数。
- 语法
# 1.把希望设置的属性值,定义成 __init__ 方法的参数 # 2.在方法内部使用, self.属性 = 形参 来接收外部传递的参数 self.属性 = 形参 # 3.在创建对象时,使用 类名(属性1, 属性2...) 调用 __init__ 方法。 对象名 = 类名(属性1, 属性2...) # 4.访问实例方法,对象名.方法名(参数)来调用函数的 对象名.方法名(参数)
class Washer(): def __init__(self, w, h): # 添加实例属性 self.width = w self.height = h def print_info(self): # 实例方法 # 类里面调用实例属性 print(f'洗衣机的宽度是{self.width}') print(f'洗衣机的高度是{self.height}') haier1 = Washer(10, 20) haier1.print_info()
4.3 __str__()
- 当使用print输出对象的时候,默认打印对象的内存地址。
- 如果类定义了
__str__
方法,那么就会打印从在这个方法中 return 的数据。
注意:
__str__
方法必须返回一个字符串
class Washer(): def __init__(self, width, height): self.width = width self.height = height def __str__(self): return '这是海尔洗衣机的说明书' haier1 = Washer(10, 20) # 这是海尔洗衣机的说明书 print(haier1)
4.4 __del__()
当删除对象时,python解释器也会默认调用__del__()方法。
在 Python 中
当使用 类名() 创建对象时,为对象 分配完空间后,自动 调用 __init__ 方法
当一个 对象被从内存中销毁 前,会 自动 调用 __del__ 方法
应用场景
__init__ 改造初始化方法,可以让创建对象更加灵活
__del__ 如果希望在对象被销毁前,再做一些事情,可以考虑一下 __del__ 方法
生命周期
一个对象从调用 类名() 创建,生命周期开始
一个对象的 __del__ 方法一旦被调用,生命周期结束
在对象的生命周期内,可以访问对象属性,或者让对象调用方法
class Washer(): def __init__(self, width, height): self.width = width self.height = height def __del__(self): print(f'{self}对象已经被删除') haier1 = Washer(10, 20) # <__main__.Washer object at 0x0000026118223278>对象已经被删除 del haier1
提示:在计算机中,通常使用十六进制表示内存地址
%d
可以以 10 进制 输出数字%x
可以以 16 进制 输出数字
五、总结
- 面向对象重要组成部分
- 类
- 创建类
class 类名(): 代码
- 对象
对象名 = 类名()
- 对象
对象名 = 类名() • 1
- 添加对象属性
- 类外面
对象名.属性名 = 值 • 1
- 类里面
self.属性名 = 值
获取对象属性
- 类外面
对象名.属性名 • 1
- 类里面
self.属性名
- 魔法方法
__init__()
: 初始化__str__()
:输出对象信息__del__()
:删除对象时调用
- 在 类的外部,通过
对象名.
访问对象的 属性和方法 - 在 类封装的方法中,通过
self.
访问对象的 属性和方法