面向对象编程:类与对象

2022.4.6面向对象编程及类与对象

  • 面向对象编程思想前戏
  • 面向过程编程与面向对象编程
  • 类与对象的概念
  • 类与对象的创建
  • 类与对象的具体操作

一、面向对象编程思想前戏

引入:人狗大战小游戏

首先,描述人和狗

# 方式一:使用字典描述
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
}
# 方式二:封装成函数
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)  # 狗dogg2攻击人p1
person_attack(p2,dog1)  # 人p2攻击狗dog1

这样,一个人与狗大战的功能狗写好了,注意观察代码,我们会发现,定义的函数人与狗并没有明显的界限,也就是说人攻击的函数也可以传入狗的数据,这样就不合理了,那么怎么让人就使用热攻击的函数,狗使用狗的呢?

结合之前的闭包函数,我们可以把攻击功能闭包在数据函数之内,将人狗数据传入字典,再将字典数据传入相关函数,这样就可以使用内部的函数且不担心人狗混合了,因为这里将数统一了,如下:

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:类其实也算对象>>>:一切皆对象

四、类与对象的创建

注意:代码编程中,先有类才能有对象!

即先定义类,后产生对象

# 定义一个学生类
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.产生对象
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)  # 北京大学

五、类与对象的具体操作

首先,定义学生类

# 定义学生类
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.将创建好的对象自动返回
给你提供这种方式能够减少代码的编写
'''
posted @ 2022-04-07 00:31  马氵寿  阅读(70)  评论(0)    收藏  举报