面向对象编程:类与对象
2022.4.6面向对象编程及类与对象
- 面向对象编程思想前戏
- 面向过程编程与面向对象编程
- 类与对象的概念
- 类与对象的创建
- 类与对象的具体操作
一、面向对象编程思想前戏
引入:人狗大战小游戏
首先,描述人和狗
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
# 方式一:使用字典描述
dog1 = {
'name': '小黑',
'type': '田园犬',
'attack_val': 30,
'life_val': 200
}
dog2 = {
'name': '小白',
'type': '恶霸犬',
'attack_val': 180,
'life_val': 500
}
person1 = {
'name': '小龙',
'type': '猛男',
'attack_val': 10,
'life_val': 1000
}
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
# 方式二:封装成函数
def get_person(name, gender, age, t_type, attack_val, life_val):
data_dict = {
'name': name,
'gender': gender,
'age': age,
't_type': t_type,
'attack_val': attack_val,
'life_val': life_val
}
return data_dict
def get_dog(name, t_type, attack_val, life_val):
data_dict = {
'name': name,
't_type': t_type,
'attack_val': attack_val,
'life_val': life_val
}
return data_dict
复制代码
- 1
- 2
- 3
- 4
- 5
# 赋值几个人与狗的对象
p1 = get_person('jason', 'male', 18, '猛男', 800, 1000)
p2 = get_person('kevin', 'female', 28, '淑女', 5, 100)
dog1 = get_dog('小黑', '松狮犬', 300, 500)
dog2 = get_dog('小白', '泰迪犬', 50, 200)
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
# 定义人攻击狗和狗攻击人的函数
def dog_attack(dog_obj, person_obj):
"""
:param dog_obj: 接收一条狗
:param person_obj: 接收一个人
"""
# 使用最简答的掉血逻辑 血量减去对方攻击力
print('当前人的血量是:%s' % person_obj.get('life_val'))
person_obj['life_val'] -= dog_obj.get('attack_val')
print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s"""%(dog_obj.get('name'),person_obj.get('name'),dog_obj.get('attack_val'),person_obj['life_val']))
def person_attack(person_obj, dog_obj):
"""
:param person_obj: 接收一个人
:param dog_obj: 接收一条狗
"""
print('当前狗的血量是:%s'%dog_obj.get('life_val'))
dog_obj['life_val'] -= person_obj.get('attack_val')
print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s"""%(person_obj.get('name'),dog_obj.get('name'),person_obj.get('attack_val'),dog_obj['life_val']))
复制代码
- 1
- 2
- 3
# 调用攻击函数
dog_attack(dog2,p1) # 狗dogg2攻击人p1
person_attack(p2,dog1) # 人p2攻击狗dog1
这样,一个人与狗大战的功能狗写好了,注意观察代码,我们会发现,定义的函数人与狗并没有明显的界限,也就是说人攻击的函数也可以传入狗的数据,这样就不合理了,那么怎么让人就使用热攻击的函数,狗使用狗的呢?
结合之前的闭包函数,我们可以把攻击功能闭包在数据函数之内,将人狗数据传入字典,再将字典数据传入相关函数,这样就可以使用内部的函数且不担心人狗混合了,因为这里将数统一了,如下:
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
def get_person(name, gender, age, t_type, attack_val, life_val):
# 将人的攻击动作放在产生人的函数内
def person_attack(person_obj, dog_obj):
"""
:param person_obj: 接收一个人
:param dog_obj: 接收一条狗
"""
print('当前狗的血量是:%s' % dog_obj.get('life_val'))
dog_obj['life_val'] -= person_obj.get('attack_val')
print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
person_obj.get('name'), dog_obj.get('name'), person_obj.get('attack_val'), dog_obj['life_val']))
data_dict = {
'name': name,
'gender': gender,
'age': age,
't_type': t_type,
'attack_val': attack_val,
'life_val': life_val,
'person_attack':person_attack
}
return data_dict
def get_dog(name, t_type, attack_val, life_val):
def dog_attack(dog_obj, person_obj):
"""
:param dog_obj: 接收一条狗
:param person_obj: 接收一个人
"""
# 使用最简答的掉血逻辑 血量减去对方攻击力
print('当前人的血量是:%s' % person_obj.get('life_val'))
person_obj['life_val'] -= dog_obj.get('attack_val')
print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
dog_obj.get('name'), person_obj.get('name'), dog_obj.get('attack_val'), person_obj['life_val']))
data_dict = {
'name': name,
't_type': t_type,
'attack_val': attack_val,
'life_val': life_val,
'dog_attack':dog_attack
}
return data_dict
p1 = get_person('jason','male',18,'猛男',800, 1000)
p2 = get_person('kevin','female',28,'淑女',10,100)
dog1 = get_dog('小黑', '松狮犬', 300, 500)
dog2 = get_dog('小白', '泰迪犬', 50, 200)
p1['person_attack'](p1,dog1)
dog1['dog_attack'](dog1,p2)
这就是面向对象编程,其实就是将数据和功能整合到一个整体,使之统一为一个功能
二、面向过程编程与面向对象编程
1、面向过程编程
就是将程序执行流程化分步操作,就像流水线一样,各自为一个整体
eg:
登录、注册、查看、删除、修改、结算等
2、面向对象编程
核心就是“对象”二字,那什么是对象?
对象其实像一个容器,能够将数据和功能整合到一起
其实,说白了python中一切皆为对象!
因此,针对面向对象编程python提供了专门的语法,使之识别度更高,更为精简,但是面向对象与面向过程本身没有优劣之分,解释实际情况使用,有时还会混合使用
三、类与对象的概念
对象:数据与功能的结合体
类:即类别、种类,相当于诸多对象共有的特征(数据,功能)
eg:
现实中,有人群、牛群、羊群、马群,比如人群,都有相同人的特征,才称之为人类,但是也有不同的特征,比如姓名、身高、体重等
ps:类其实也算对象>>>:一切皆对象
四、类与对象的创建
注意:代码编程中,先有类才能有对象!
即先定义类,后产生对象
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
# 定义一个学生类
class Student:
school = '清华大学'
def chose_course(self):
print('学生选课功能')
注意:类体代码无须调用就会执行,产生类的名称空间
1.语法结构如下:
class 类名: # 1.class是定义类的关键字2.类名类似于函数名 但是首字母推荐大写
类体代码 # 类体代码就是存放对象公共数据和功能的地方
数据: 变量名 = 变量值
功能: 函数
2.查看类名称空间的方法>>>:__dict__
print(Student.__dict__) # 返回值是个字典
3.获取类数据和功能的方式:
方式1:字典式取值
print(Student.__dict__['school']) # 获取类中的属性
print(Student.__dict__['choose_course']) # 获取类中的属性
方式2:句点符
print(Student.school) # # 获取类中的属性school
print(Student.choose_course) # # 获取类中的属性choose_course
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
# 产生对象:类加括号
1.产生对象
obj1 = Student() # 类名加括号就是在产生一个对象
obj2 = Student()
print(obj1.__dict__, obj2.__dict__) # {} {}
这里通过赋值给变量名的方式,使用变量名调用__dict__得到的是空字典,但是obj仍然可以通过句点符点的方式获取和修改类中的数据,如下:
2.获取和修改数据
获取数据:
print(obj1.school) # 清华大学
print(obj1.choose_course) # bound method,即绑定的方法
修改数据:
Student.school = '北京大学' # 方式1
Student.__dict__['school'] = '北京大学' # 方式2
3.可以产生多个对象
这里要注意,不管类赋值给哪个变量名,都可以使用此变量名,访问类中数据,如下
print(obj1.school) # 北京大学
print(obj2.school) # 北京大学
五、类与对象的具体操作
首先,定义学生类
复制代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
# 定义学生类
class Student:
school = '清华大学' # 学生类公共的数据
def choose_course(self): # # 学生类公共的功能
print('学生选课功能')
obj1 = Student() # 目前对象没有各自独有属性
obj2 = Student() # 目前对象没有各自独有属性
print(obj1.__dict__) # {},大白话就是给字典添加键值对
print(obj2) # <__main__.Student object at 0x0000020F2C5EAF60>
方案1:逐步添加
obj1.name = 'jason'
obj1.age = 18
obj1.gender = 'male'
obj2.name = 'kevin'
obj2.age = 28
obj2.gender = 'female'
print(obj1.__dict__) # 获取所有类数据
方案2:封装函数
def int(obj,name,age,gender): # 获取学生数据的函数
obj.name = name
obj.age = age
obj.gender = gender
init(obj1,'jason',18,'male') # 传入数据到函数
init(obj2,'kevin',28,'female')
print(obj1.name) # 获取类中数据
方案3:在方案2的基础上,使用面向对象的方式,将函数写到类中,然后就可以使用类调用函数
Student.int(obj1,'jason',18,'male') # 产生对象obj1
Student.int(obj2,'Kevin',28,'female') # 产生对象obj2
方案4:在方案3的基础上,python中针对给对象创建独有数据的函数名,专门定义了一个固定方法:__init__
只需要将int改为__init__即可,固定搭配
class Student:
def __int__(self,name,age,gender):
# 对象调用类中函数 会将当前调用的对象当做第一个参数自动传入,默认写为self
obj.name = name
obj.age = age
obj.gender = gender
school = '清华大学' # 学生类公共的数据
def choose_course(self): # # 学生类公共的功能
print('学生选课功能')
obj1 = Student('jason', 18, 'male') # 优化操作,不再需要调用内部函数和obj参数
obj2 = Student('kevin', 28, 'female')
'''
注意:
类中的__init__方法会在类产生对象的时候自动执行
类产生对象的具体步骤
1.先创建一个没有独有数据的空对象 {}
2.将空对象和类括号内传入的数据一并交给__init__执行
__init__的第一个参数就是对象本身
__init__(obj,name,age,gender)
3.将创建好的对象自动返回
给你提供这种方式能够减少代码的编写
'''
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步