面向对象,类
今日内容概要
强调:今日内容以理论为主,仅仅是一个思想的解读而已
- 面向对象编程思想前戏
- 面向过程编程与面向对象编程
- 类与对象的概念
- 代码编写类
- 代码产生对象
- 类与对象的具体操作
面向对象编程思想前戏
以人狗大战游戏为例
# 1.描述人和狗
'''描述人和狗的方式1:使用字典一个个描述'''
# 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
# }
此方法代码较多,尤其是当person 和 dog 多的时候 代码写起来就很繁琐
''方式2:封装成函数 减少代码冗余'''
# 定义专门用来描述人和狗的函数(最好单独编写)
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
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)
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']))
# 狗咬人
# dog_attack(dog2,p1)
# print(p1)
#当前人的血量是:1000
# 狗:小白 咬了人:jason 一口 人掉血:50 剩余血量:950
# {'name': 'jason', 'gender': 'male', 'age': 18, 't_type': '猛男', 'attack_val': 800, 'life_val': 950}
# 人锤狗
# person_attack(p2, dog1)
# print(dog1)
#当前狗的血量是:500
# 人:kevin 锤了狗:小黑 一下 狗掉血:5 剩余血量:495
# {'name': '小黑', 't_type': '松狮犬', 'attack_val': 300, 'life_val': 495}
# '''人调用了狗的攻击动作'''
# dog_attack(p1, dog1) # 人的血量是:500
# 狗:jason 咬了人:小黑 一口 人掉血:800 剩余血量:-300
# '''狗调用了人的攻击工作'''
# person_attack(dog2,p2) # 当前狗的血量是:100
# 人:小白 锤了狗:kevin 一下 狗掉血:50 剩余血量:50
此方法不能准确调用功能,容易造成混乱.
"""如何做到只有人可以调用人的攻击动作 狗调用狗的攻击动作"""
# 其实就是想让人的数据跟人的功能绑定 狗的数据跟狗的功能绑定
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.面向过程编程
将程序的执行流程化 即分步骤操作,在分布的过程中解决问题.
过程可以理解为流水线, 面向过程编程可以理解为在创造一条流水线.
2. 面向对象编程
核心就是"对象"二字. 对象就是一个"容器" 将数据与功能整合在一起.只要符合此条件就可以称之为对象.
eg:人狗大战最后的函数内部含有数据和功能 可以称之为面向对象编程
模块文件内部含有数据和功能 也可以称之为面向对象编程. 即 在python中: 一切皆对象.
python 针对面向对象编程提供了专门的语法,识别度更高,语法更精简.
eg:人 动物 游戏角色
面向过程与面向对象两者没有优劣之分,具体要结合实际情况.
很多时候两者是混合使用的.
#把大象关进冰箱的不同思路:
#面向过程思想:
1打开冰箱门。
2.将大象关进冰箱。
3.关闭冰箱门。
#面向对象思想:
1.找到一个能够打开冰箱的人。
2.找到能够将大象关进冰箱的人。
3.找到一个能够关闭冰箱的人。
类与对象的概念
# 对象: 数据与功能的结合体
类: 类别,种类 相当于诸多对象共有的特征(数据,功能)
类是用来描述公共特征的, 不同的特征应该有对象自己描述.
类也是对象.
类与对象的创建
在代码编程中 先有类才产生对象 [类可以看成是祖宗, 对象是子子孙孙]
# 先定义类 后产生对象
# 学生类
class Student:
# 学生类公共的数据
school = '清华大学'
# 学生类公共的功能
def choose_course(self):
print('学生选课功能')
#语法结构
class 类名:
类体代码
1.class是定义类的关键字
2.类名类似于函数名 但是首字母推荐大写 用于区分
3.类体代码就是存放对象公共数据和功能的地方
数据: 变量名 = 变量值
功能: 函数
#查看名称空间的方法>>>:__dict__
print(Student.__dict__) # 返回值是一个字典
print(Student.__dict__['school']) # 获取类中的属性
print(Student.__dict__['choose_course']) # 获取类中的属性
"""类获取数据和功能有一个简便的方式>>>:句点符"""
print(Student.school) # 清华大学
'''类有一个方法:__dict__,调用这个方法可以打印出类的所有属性,返回的是一个字典的形式,下面我们把类的属性打印出来'''
print(Student.choose_course)
#<function Student.choose_course at 0x00000281EAA6E2F0>
对象的实例化
class Student:
def __init__(self, name, age, gender):
'''该方法就一个功能>>>:给对象添加独有的数据'''
self.name = name # obj.__dict__['name'] = name
self.age = age # obj.__dict__['age'] = age
self.gender = gender # obj.__dict__['gender'] = gender
# 学生类公共的数据
school = '清华大学'
# 学生类公共的功能
def choose_course(self):
print('学生选课功能')
'''类中针对给对象创建独有数据的函数名 专门定义了一个固定的方法 '''
obj1 = Student('jason', 18, 'male')
obj2 = Student('kevin', 28, 'female')
print(obj1.__dict__)
#{'name': 'jason', 'age': 18, 'gender': 'male'}
print(obj2.__dict__)
#{'name': 'kevin', 'age': 28, 'gender': 'female'}
"""
类中的__init__方法会在类产生对象的时候自动执行
类产生对象的具体步骤
1.先创建一个没有独有数据的空对象 {}
2.将空对象和类括号内传入的数据一并交给__init__执行
__init__的第一个参数就是对象本身
__init__(obj,name,age,gender)
3.将创建好的对象自动返回
ps:针对括号内第一个形参self其实就是一个普通的变量名而已
只不过该变量名将来专门接收对象的 所以给它起了个固定的名字叫self
"""
绑定方法
在类中定义的函数默认都是绑定给对象使用的 即对象来调,会自动将对象当作第一个参数传入.
class Student:
school = '清华大学'
# __init__方法不要自己去调用
def __init__(self, name, age):
self.name = name
self.age = age
def func(self):
print('%s正在调用func方法'%self.name)
obj1 = Student('jason', 18)
obj2 = Student('kelly', 22)
# 类调用类中函数 有几个参数就需要传几个参数
Student.func(123,222)
# 对象调用类中函数 会将当前调用的对象当做第一个参数自动传入