面向对象基础
目标
- 理解面向对象
- 类和对象
- 添加和获取对象属性
- 魔法方法
1 理解面向对象
面向对象是一种抽象化的编程思想,很多编程语言中都有的一种思想。
例如: 洗衣服
思考: 几种途径可以完成洗衣服?
答: 手洗 和 机洗
手洗: 找盆 – 放水 加洗衣粉 – 浸泡 搓洗 水 – 倒水 漂洗N次 晾晒。机洗: 打开洗衣机 – 放衣服 – 加洗衣粉 按下开始按钮 晾晒
思考: 对比两种洗衣服途径,同学们发现了什么?答: 机洗更简单
思考: 机洗,只需要找到一台洗衣机,加入简单操作就可以完成洗衣服的工作,而不需要关心洗衣机内部发生了什么事情。
总结:
面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么事。
面向对象的好处,会使我们的代码更简单,化简代码化简逻辑
2 类和对象
思考:洗衣机洗衣服描述过程中,洗衣机其实就是一个事物,即对象,洗衣机对象哪来的呢?
答: 洗衣机是由工厂工人制作出来
思考: 工厂工人怎么制作出的洗衣机?
答: 工人根据设计师设计的功能图纸制作洗衣机。
总结: 图纸一洗衣机一洗衣服。
在面向对象编程过程中,有两个重要组成部分:类 和 对象
也就是说图纸用来创建洗衣机,其实在面向对象中类就相当于创建洗衣机的图纸,而我们的对象就是我们的实物洗衣机
类和对象的关系就是:用类创建一个对象,有了类我就能通过类创建对象
创建这个词可以理解为实例化,也可以说成用类实例化一个对象
2.1 理解类和对象
类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。
- 特征即是属性
- 行为即是方法
类就是制造洗衣机时要用到的图纸,也就是说类是用来创建对象,这时候我先思考图纸里面都有什么
如上图就是一个洗衣机的图纸,在图纸中可以看到有长宽高的尺寸,而这些尺寸在程序中通过变量即可存储,洗衣机我们都知道有很多功能,所以需要标识不同的按钮对应不同的功能。
功能:
- 放水
- 甩干
- 洗衣
而这些功能我们都知道只需要点击按钮就能运转起来从而完成我们的相关工作
所以功能在我们程序中可以理解为函数
2.1.2 对象
对象是类创建出来的真实存在的食物,例如:洗衣机
注意:开发中,先有类,再有对象
2.2 面向对象实现方法
2.2.1 定义类
python 2 中类分为:经典类和新式类
-
语法
class 类名(): 代码 ......
注意:类名要满足标识符名称规则,同时遵循大驼峰命名习惯
体验:
# 创建类
class Washer():
def wash(self):
print("洗衣服功能")
2.2.2 创建对象
对象又名实例
-
语法
对象名 = 类名()
-
体验
# 需求: 洗衣机,功能:洗衣服、脱水
# 1.定义洗衣机类
class Washer():
def wash(self):
print("洗衣服功能")
# 2.创建对象,海尔牌洗衣机
haier = Washer()
# 3.验证成果,输出内存地址
print(haier)
# 4.调用 Wahser 类中的 wash() 方法
haier.wash()
[11:06:08 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
<__main__.Washer object at 0x7f099edc3670>
洗衣服功能
2.2.3 self
self 指的调用函数的对象
如下代码:
# 1.定义类,功能洗衣服
class Washer():
def wash(self):
print('洗衣服')
# 输出地址 <__main__.Washer object at 0x7f02e3806640>
print(self)
# 2.创建对象
harier = Washer()
# 输出 harier 变量内存地址
print(harier)
# 调用 wash 函数
harier.wash()
# 可以看到 self 输出的其实就是 wash 函数对象
[13:37:16 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
<__main__.Washer object at 0x7f02e3806640>
洗衣服
<__main__.Washer object at 0x7f02e3806640>
结论:
由于打印对象和打印 self 得到的内存地址相同的,所以 self 指的是调用该函数的对象
2.2.4 一个类创建多个对象
我们都知道在生活工作中一张图纸可以创建很多个洗衣机,那么在我们的编程中一个类也可以创建出来很多个编程对象
如代码:
# 1.一个类可以创建多个对象
# 2.多个对象都调用函数的时候 self 地址是否相同
class Washer():
def wash(self):
print('洗衣服')
print(self)
harier1 = Washer()
harier1.wash()
harier2 = Washer()
harier2.wash()
[14:16:41 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
洗衣服
<__main__.Washer object at 0x7f071c12d640>
洗衣服
<__main__.Washer object at 0x7f071c04d610>
总结:
由此可见一个类可创建多个对象,并且内存地址都不一样,在工作中我们可以按照需求实现一个类创建出多个不同的对象
3 添加和获取对象属性
属性即是特征,比如:洗衣机的、长宽高、重量等
对象属性既可以在类外面添加和获取,也能在类里面添加和获取
因为不同的对象特征肯定是不同的,那么这个时候我们就需要通过不得变量或者不同的方法来实现标识不同的对象
3.1 类外面添加对象属性
- 语法:
对象名.属性名 = 值
- 体验
haier1.width = 500
haier1.height = 800
代码如下:
# 1.创建类
class Washer():
def wash(self):
print('洗衣机')
haier1 = Washer()
# 赋值两个属性
haier1.width = 500
haier1.height = 800
# 获取数据
print(f'洗衣机高度{haier1.height}\n洗衣机宽度{haier1.width}')
[14:38:17 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
洗衣机高度800
洗衣机宽度500
3.2 类里面获取对象属性
-
语法:
self.属性名
-
体验
# 1.创建类
class Washer():
def print_info(self):
# 在类中获取实例属性
print(f'haier1 洗衣机的宽度是{self.Width}')
print(f'haier1 洗衣机的高度是{self.Height}')
# 创建实例
haier1 = Washer()
# 给属性赋值
haier1.Width = '500'
haier1.Height = '800'
# 调用 print_info 实例方法
haier1.print_info()
[14:48:17 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
haier1 洗衣机的宽度是500
haier1 洗衣机的高度是800
4 魔法方法
在 python 中,_XX_()
的函数叫做魔法方法,指的是具有特殊功能的函数
4.1 __init__
4.1.1 体验 __init__
思考: 洗衣机的宽度高度是与生俱来的属性,可不可以在生产过程中就赋予这些属性呢?
答:理应如此,所以这些属性应该在创建对象之前就应该存在,通过 __init__
实现
__init__
方法的作用:初始化对象
# 目标:定义 init 魔法方法设置初始化属性,并访问调用
# 1.创建类
class Washer():
# 定义 __init__ 添加实例属性,定义高度和宽度
def __init__(self) :
self.Width = 500
self.Height = 800
# 通过 self 访问并调用实例属性
def print_info(self):
# 类里调用实例属性
print(f'haier1 洗衣机的宽度是{self.Width}')
print(f'haier1 洗衣机的高度是{self.Height}')
# 实例化对象
haier1 = Washer()
haier1.print_info()
[14:48:28 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
haier1 洗衣机的宽度是500
haier1 洗衣机的高度是800
可以看到在我们的实例化对象中并没有对 Width、Height 两个属性进行调用与赋值,但是在 init 函数中已经实现了初始化
注意
__init__()
方法,在创建一个对象时默认被调用,不需要手动调用__init__(self)
中的self
参数,不需要开发者传递,python
解释器会自动把当前的对象引用传递过去。
4.1.2 带参数的__init__()
思考:一个类可以创建多个对象,如何对不同的对象设置不同的初始化属性呢?
答:传参数
__init__()
函数不用程序员手动调用,而是在创建实例对象的时候自动调用,所以在代码中只要创建了实例对象并传参就会调用 __init__()
函数
在下面代码中,我们直接在 __init__()
函数中传参从而实现不同的属性值
# 1. 定义类:带参数的 init:宽度和高度,实例方法:调用实例属性
class Washer():
# 通过 __init__ 魔法函数并传入 width,height 参数
def __init__(self,width,height):
# 给 self 实例进行赋值
self.width = width
self.height = height
# 通过 self 访问并调用实例方法
def print_info(self):
print(f'haier1 洗衣机的宽度是{self.width}')
print(f'haier1 洗衣机的高度是{self.height}')
# 2.创建对象,创建多个对象且属性值不同,调用实例方法实现输出
# 创建 haier 实例的同时传入 width = 30,height = 40,并调用 print_info 函数
haier = Washer(30,40)
haier.print_info()
# 创建 haier1 实例的同时传入 width = 30,height = 40,并调用 print_info 函数
haier1 = Washer(70,80)
haier1.print_info()
[15:31:36 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
haier1 洗衣机的宽度是30
haier1 洗衣机的高度是40
haier1 洗衣机的宽度是70
haier1 洗衣机的高度是80
4.2 __str__()
当使用 print 输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__()
方法,那么就会打印从这个方法中获取的 return 返回值
一般__str__()
方法放置的都是一些解释说明的内容,当我们在打印对象的时候不在输出内存地址,而是输出这些解释说明的内容
# 1.定义类
class Washer():
def __init__(self,width,height):
self.width = width
self.height = height
def __str__(self):
return '这是洗衣机说明书'
# 2.创建实例
haier = Washer(40,50)
# 打印内容
print(haier)
# 可以看到输出的内容是 __str__ 魔法方法中的返回值
[15:31:36 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
这是洗衣机说明书
4.3 __del__()
当删除对象时,python 解释器也会默认调用 __del__()
方法
在下面代码中,可以看到我们在 washer 类中定义了 __del__()
方法,然后通过调用内置函数 del 删除了 haier1 这个对象,就会调用 __del__()
方法中的输出内容,当然我们不通过内置函数 del
也会自动调用 __del__()
方法,因为在程序执行完毕之后退出程序我们都知道内存会自动释放并删除对应函数中的内容从而自动调用 __del__()
1.不调用 del 内置函数实现
# 1.定义类
class Washer():
def __init__(self,width,height) -> None:
self.width = width
self.height = height
def __del__(self):
print(f'{self}对象已被删除')
# 2.创建 haier1 实例
haier1 = Washer(10,20)
# 可以看到我们在程序中并没有调用 del 方法,也能够调用 __del__ 魔法方法
[15:48:58 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
<__main__.Washer object at 0x7fa43d57d640>对象已被删除
2.调用 del 内置函数实现
# 1.定义类
class Washer():
def __init__(self,width,height) -> None:
self.width = width
self.height = height
def __del__(self):
print(f'{self}对象已被删除')
# 2.创建 haier1 实例
haier1 = Washer(10,20)
# 调用 del 函数
del haier1
[15:59:14 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
<__main__.Washer object at 0x7f87a7d7f640>对象已被删除