面向对象

内容概要

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

面向对象编思想前戏

人狗大战的小游戏

方式1


    1,描述人和狗特征
    '''描述人和狗的方式1:使用字典进行逐一描述'''

    dog1 = {
        'name':'旺财',  
        'dog_type':'中华田园犬',
        'attack_val':50,  # 战斗力
        'life_val':300  # 生命值
    }
    dog2 = {
        'name':'小黑',
        'dog_type':'柴犬',
        'attack_val':30,  # 战斗力
        'life_val':200  # 生命值
    }
    person1 = {
        'name':'小明',
        'man_type':'猛男',
        'attack_val': 25,  # 战斗力
        'life_val': 1000  # 生命值
    }


方式2


    '''方式2::封装成函数 减少代码冗余'''
    # 分别定义用来描述人和狗的函数
    def get_person(name,gender,age,man_type,attack_val,life_val):
        data_dict = {
                'name': name,
                'gender': gender,  # 性别
                'age': age,
                't_type': man_type,
                'attack_val': attack_val,
                'life_val': life_val
            }
        return data_dict  # 返回数据字典


    def get_dog(name, dog_type, attack_val, life_val):
        data_dict = {
            'name': name,
            't_type': dog_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)
    # 人锤狗
    person_attack(p2, dog1)
    print(dog1)
    '''
        当前人的血量是:1000
        狗:小白 咬了人:小明 一口 人掉血:50 剩余血量:950
        {'name': '小明', 'gender': 'male', 'age': 18, 't_type': '猛男', 'attack_val': 200, 'life_val': 950}
        当前狗的血量是:500
        人:Tom 锤了狗:小黑 一下 狗掉血:5 剩余血量:495
        {'name': '小黑', 't_type': '松狮犬', 'attack_val': 300, 'life_val': 495}
    '''

    # '''人调用了狗的攻击动作'''
    # dog_attack(p1, dog1)
    # '''狗调用了人的攻击工作'''
    # person_attack(dog2,p2)
    '''但当人和狗调换过来就会出现人咬狗,狗打人错乱的情况'''

完善方式2


    '''完善逻辑 要做到只有人才能调用人的函数,只有狗才可调用狗的函数'''
    # 其实就是想让人的数据跟人的功能绑定 狗的数据跟狗的功能绑
    '将人的攻击动作放到产生人的函数内进行整合'
    def get_person(name,gender,age,man_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': man_type,
                'attack_val': attack_val,
                'life_val': life_val,
                'person_attack':person_attack
            }
        return data_dict  # 返回数据字典


    def get_dog(name, dog_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': dog_type,
            'attack_val': attack_val,
            'life_val': life_val,
            'dog_attack':dog_attack
        }
        return data_dict  # 返回数据字典

    # 调用函数传参
    p1 = get_person('小明', 'male', 18, '猛男', 200, 1000)
    p2 = get_person('Tom', 'female', 20, '淑女', 5, 500)
    dog1 = get_dog('小黑', '松狮犬', 300, 500)
    dog2 = get_dog('小白', '泰迪犬', 50, 200)
    p1.get('person_attack')(p1,dog2)
    dog1.get('dog_attack')(dog1,p2)
    """
    上述操作其实就是将数据与功能进行绑定 
        不再是所有的数据都可以调用任意的功能
    """
    # 上述将数据与功能整合到一起的操作其实就是 面向对象编程的思想
    

编程思想

    1.面向过程编程
        将程序的执行流程化 即分步操作 分步的过程中解决问题
        eg:注册、登录、结算购物车...
          """注册:第一步获取用户名 第二步比对用户名数据 ..."""
          """结算:第一步获取购物车数据 第二步计算钱数   ..."""
        过程可以理解成是流水线 面向过程编程可以理解成是在创建一条流水线


    2.面向对象编程
        核心就是'对象'二字 
            对象其实就是一个"容器" 将数据与功能整合到一起
      只要是符合上述描述的事物都可以称之为是对象!!!
        eg:
          人狗大战最后的函数内部含有数据和功能 可以称之为面向对象编程
          模块文件内部含有数据和功能 也可以称之为面向对象编程
      """仔细的想想会发现 python中一切皆对象!!!"""
      python针对面向对象编程提供了专门的语法 识别度更高 编写更精简
            eg:人、动物、游戏角色
    """
    面向过程与面向对象两者没有优劣之分 具体要结合实际情况
    甚至很多时候两者是混合在一起的!!! 思想占据的比例不同而已
    """

类与对象的概念

    对象:数据与功能的结合体
    类:即类别,由诸多对象共有的特征
    """
    eg:
    一个人(对象)    >>>     一群人(人类)
    一条狗(对象)    >>>     一群狗(犬类)
        用来描述对象的'相同'的特征即>>>类
            黄种人 黑种人 白种人都属于人类 但是彼此也有不同的特征
            类只能描述出公共的特征!!! 不同的特征应该由对象自己描述!!!
    """
    类也可以算作是对象>>>:在python中一切皆对象

类与对象的操作

类与对象的创建

    '''在代码的编写中要先有类才能有对象'''
    # 先定义类 后产生对象
    """
    语法结构
    class 类名:
        类体代码
    1.class是定义类的关键字
    2.类名类似于函数名 但是首字母推荐大写 用于区分
    3.类体代码就是存放对象公共数据和功能的地方
        数据: 变量名 = 变量值
        功能: 函数
    """

    # 以学生为例 
    class Student:  # 创建学生类
        # 学生类中公用的数据
        school = '南咖学院'  # 学校名称
        position = '斗罗大陆'  # 学校地址
        def choose_course(self): 
            print("""选课功能
            1.佛怒糖莲
            2.斗气化马
            3.武魂真身
            """)
    """类体代码无需调用就会执行 产生类的名称空间"""

    # 查看名称空间的方法>>>:__dict__
    # print(Student.__dict__)  # 返回值是一个字典
    # print(Student.__dict__['school'])  # 获取类中的属性
    # print(Student.__dict__['choose_course'])  # 获取类中的属性
    """类获取数据和功能有一个简便的方式>>>:句点符"""
    print(Student.school)
    print(Student.choose_course)

    """如何产生对象:类名加括号"""
    obj1 = Student()  # 类名加括号就是在产生一个对象
    obj2 = Student()
    # print(obj1.__dict__, obj2.__dict__)  # {} {}
    # print(obj1.school)  # 南咖学院
    # print(obj2.position)  # 斗罗大陆
    # print(obj1.choose_course)  # bound method
    # print(obj2.choose_course)  # bound method
    print(obj1.school)  # 南咖学院
    print(obj2.position)  # 斗罗大陆
    Student.school = '北京大学'  # Student.__dict__['school'] = '北京大学'  修改名字与值的对应关系
    print(obj1.school)  # 北京大学
    print(obj2.position)  # 斗罗大陆

对象的实例化

方案1

    # 以学生为例
    class Student:  # 创建学生类
        # 学生类中公用的数据
        school = '南咖学院'  # 学校名称
        position = '斗罗大陆'  # 学校地址
        def choose_course(self):
            print("""选课功能
            1.佛怒糖莲
            2.斗气化马
            3.武魂真身
            """)
    obj1 = Student()  # 目前对象没有自己独有的属性

    '''方案1:逐步给对象添加独有的数据'''
    obj1.__dict__['name'] = '唐三'  # obj1.name = '唐三'
    obj1.__dict__['age'] = 18  # obj1.age = 18
    obj1.__dict__['gender'] = 'male'  # obj1.gender = 'male'
    print(obj1.name,obj1.age,obj1.gender,)

方案2

    # 以学生为例
    class Student:  # 创建学生类
        # 学生类中公用的数据
        school = '南咖学院'  # 学校名称
        position = '斗罗大陆'  # 学校地址
        def choose_course(self):
            print("""选课功能
            1.佛怒糖莲
            2.斗气化马
            3.武魂真身
            """)
    obj1 = Student()  # 目前对象没有自己独有的属性
    '''方案2:将冗余的添加步骤封装成函数'''
    obj1 = Student()  # 目前对象没有自己独有的属性
    def init(obj,name,age,gender):
        obj.name = name  # obj.__dict__['name'] = name
        obj.age = age  # obj.__dict__['age'] = age
        obj.gender = gender  # obj.__dict__['gender'] = gender
    init(obj1,'jason',18,'male')
    init(obj2,'kevin',28,'female')
    print(obj1.name)  # jason
    print(obj2.name)  # kevin

方案3

    # 以学生为例
    class Student:  # 创建学生类
        def set_info(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
        # 学生类中公用的数据
        school = '南咖学院'  # 学校名称
        position = '斗罗大陆'  # 学校地址
        def choose_course(self):
            print("""选课功能
            1.佛怒糖莲
            2.斗气化马
            3.武魂真身
            """)

    '''方案3:简单的封装成函数没有提现出面向对象整合的精髓>>>:将函数写到类中去'''
    obj1 = Student()
    obj2 = Student()
    Student.set_info(obj1,'jason',18,'male')
    Student.set_info(obj2,'kevin',28,'female')
    print(obj1.name)  # jason
    print(obj2.name)  # kevin

方案4


    # 以学生为例
    class Student:  # 创建学生类
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
        # 学生类中公用的数据
        school = '南咖学院'  # 学校名称
        position = '斗罗大陆'  # 学校地址
        def choose_course(self):
            print("""选课功能
            1.佛怒糖莲
            2.斗气化马
            3.武魂真身
            """)
    '''方案4:类中针对给对象创建独有数据的函数名 专门定义了一个固定的方法'''
    obj1 = Student('jason', 18, 'male')
    obj2 = Student('kevin', 28, 'female')
    print(obj1.__dict__)
    print(obj2.__dict__)
    """
    类中的__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)

        def index(self):
            print('%s正在调用index方法'%self.name)

    obj1 = Student('jason', 18)
    # print(obj1)
    obj2 = Student('kevin', 28)
    # 类调用类中函数 有几个参数就需要传几个参数
    # Student.func(123,222)
    # 对象调用类中函数  会将当前调用的对象当做第一个参数自动传入
    # obj1.func()
    # obj2.func()
    # print(obj1.func)
    # print(obj2.index)
    '''所以应该能理解为什么类中所有的函数第一个参数都是self'''

posted @ 2022-04-06 22:38  Mr_胡萝卜须  阅读(49)  评论(0)    收藏  举报