面向对象

1. 面向对象编程思想前戏

# 人狗大战小游戏
# 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
}
'''方式2:封装成函数 减少代码冗余'''


# 定义专门用来描述人和狗的函数(最好单独编写)
def init_human(name, gender, age, attack_val, life_val):
    data_dict = {
        'name': name,
        'gender': gender,
        'age': age,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return data_dict


def init_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


human1 = init_human('李四', 'male', 18, 666, 1)
human2 = init_human('梅六', 'female', 28, 6, 100)
dog1 = init_dog('小黑', '贵宾犬', 300, 500)
dog2 = init_dog('小白', '泰迪犬', 50, 200)


def dog_attack(dog_obj, human_obj):
    """
    :param dog_obj: 接收一条狗
    :param person_obj: 接收一个人
    """
    # 使用最简答的掉血逻辑  血量减去对方攻击力
    print('当前人的血量是:%s' % human_obj.get('life_val'))
    human_obj['life_val'] -= dog_obj.get('attack_val')
    print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
        dog_obj.get('name'), human_obj.get('name'), dog_obj.get('attack_val'), human_obj['life_val']))


def human_attack(human_obj, dog_obj):
    """
    :param person_obj: 接收一个人
    :param dog_obj: 接收一条狗
    """
    print('当前狗的血量是:%s' % dog_obj.get('life_val'))
    dog_obj['life_val'] -= human_obj.get('attack_val')
    print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
        human_obj.get('name'), dog_obj.get('name'), human_obj.get('attack_val'), dog_obj['life_val']))


# 狗咬人
dog_attack(dog2, human1)
print(human1)
# 人锤狗
human_attack(human2, dog1)
print(dog1)
'''人调用了狗的攻击动作'''
dog_attack(human1, dog1)
'''狗调用了人的攻击工作'''
human_attack(dog2, human2)

"""如何做到只有人可以调用人的攻击动作 狗调用狗的攻击动作"""


# 其实就是想让人的数据跟人的功能绑定 狗的数据跟狗的功能绑定
def init_human(name, gender, age, 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,
        'attack_val': attack_val,
        'life_val': life_val,
        'person_attack': person_attack
    }
    return data_dict


def init_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


human1 = init_human('李四', 'male', 18, 666, 1)
human2 = init_human('梅六', 'female', 28, 6, 100)
dog1 = init_dog('小黑', '贵宾犬', 300, 500)
dog2 = init_dog('小白', '泰迪犬', 50, 200)
human1['person_attack'](human1, dog1)
dog1['dog_attack'](dog1, human2)
"""
上述操作其实就是将数据与功能进行绑定
    不再是所有的数据都可以调用任意的功能
"""
# 上述将数据与功能整合到一起的操作其实就是 面向对象编程的思想

 

 

2. 编程思想

1.面向过程编程
    将程序的执行流程化 即分步操作 分步的过程中解决问题
      eg:注册、登录、结算购物车...
      """注册:第一步获取用户名 第二步比对用户名数据 ..."""
      """结算:第一步获取购物车数据 第二步计算钱数   ..."""
    过程可以理解成是流水线 面向过程编程可以理解成是在创建一条流水线
  
  
2.面向对象编程
    核心就是'对象'二字 
        对象其实就是一个"容器" 将数据与功能整合到一起
  只要是符合上述描述的事物都可以称之为是对象!!!
      eg:
      人狗大战最后的函数内部含有数据和功能 可以称之为面向对象编程
      模块文件内部含有数据和功能 也可以称之为面向对象编程
  """仔细的想想会发现 python中一切皆对象!!!"""
  python针对面向对象编程提供了专门的语法 识别度更高 编写更精简
"""
面向过程与面向对象两者没有优劣之分 具体要结合实际情况
甚至很多时候两者是混合在一起的!!! 思想占据的比例不同而已
"""

 

 

3. 类与对象的概念

对象:数据与功能的结合体
类:即类别、种类 相当于诸多对象公有的特征(数据、功能)!!!
"""
在现实生活中 
    人                    对象
    一群人                    人类
    狗                        对象
    一群狗                               犬类
上述中的人类、犬类是用来描述什么的?
    就是用来描述多个对象'相同'特征的名词
    黄种人 黑种人 白种人都属于人类 但是彼此也有不同的特征
    类只能描述出公共的特征!!! 不同的特征应该由对象自己描述!!!
"""
类其实也算对象>>>:一切皆对象    

 

 

4. 类与对象的创建

# 在代码编程中是先有类才能有对象
# 先定义类 后产生对象
# 学生类
class School:
    # 学生类公共的数据
    school = 'python_cat'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


"""类体代码无需调用就会执行 产生类的名称空间"""
"""
语法结构
class 类名:
    类体代码
1.class是定义类的关键字
2.类名类似于函数名 但是首字母推荐大写 用于区分
3.类体代码就是存放对象公共数据和功能的地方
    数据: 变量名 = 变量值
    功能: 函数
"""
# 查看名称空间的方法>>>:__dict__
print(School.__dict__)  # 返回值是一个字典1
print(School.__dict__['school'])  # 获取类中的属性
print(School.__dict__['choose_course'])  # 获取类中的属性
"""类获取数据和功能有一个简便的方式>>>:句点符,即.号"""
print(School.school)
print(School.choose_course)

"""如何产生对象:类名加括号"""
school_obj1 = School()  # 类名加括号就是在产生一个对象
school_obj2 = School()
print(school_obj1.__dict__, school_obj2.__dict__)  # {} {}
print(school_obj1.school)  # python_cat
print(school_obj2.school)  # python_cat
print(school_obj1.choose_course)  # bound method
print(school_obj2.choose_course)  # bound method
print(school_obj1.school)  # python_cat
print(school_obj2.school)  # python_cat
School.school = '6666'  # School.__dict__['school'] = '6666'  修改名字与值的对应关系
print(school_obj1.school)  # 6666
print(school_obj2.school)  # 6666

 

 

3. 对象的实例化

# 学生类
class Student:
    # 学生类公共的数据
    school = 'python_cat'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


school_obj1 = Student()  # 目前对象没有自己独有的属性
school_obj2 = Student()  # 目前对象没有自己独有的属性
print(school_obj1.__dict__)  # 大白话就是给字典添加键值对
print(school_obj2.__dict__)  # 大白话就是给字典添加键值对
'''方案1:逐步给对象添加独有的数据'''


class Student:
    # 学生类公共的数据
    school = 'python_cat'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


school_obj1 = Student()  # 目前对象没有自己独有的属性
school_obj2 = Student()  # 目前对象没有自己独有的属性
school_obj1.__dict__['name'] = 'dragon'  # school_obj1.name = 'dragon'
school_obj1.__dict__['age'] = 18  # school_obj1.age = 18
school_obj1.__dict__['gender'] = 'male'  # school_obj1.gender = 'male'

school_obj2.__dict__['name'] = 'jerry'  # school_obj2.name = 'jerry'
school_obj2.__dict__['age'] = 2  # school_obj2.age = 28
school_obj2.__dict__['gender'] = 'female'  # school_obj2.gender = 'female'
print(school_obj1.__dict__, school_obj2.__dict__)
print(school_obj1.name)  # dragon
print(school_obj2.name)  # jerry
'''方案2:将冗余的添加步骤封装成函数'''


class Student:
    # 学生类公共的数据
    school = 'python_cat'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


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

school_obj1 = Student()  # 目前对象没有自己独有的属性
school_obj2 = Student()  # 目前对象没有自己独有的属性
init(school_obj1, 'dragon', 18, 'male')
init(school_obj2, 'jerry', 28, 'female')
print(school_obj1.name)
print(school_obj2.name)
'''方案3:简单的封装成函数没有提现出面向对象整合的精髓>>>:将函数写到类中去'''


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 = 'python_cat'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


school_obj1 = Student()
school_obj2 = Student()
Student.init(school_obj1, 'dragon', 18, 'male')
Student.init(school_obj2, 'jerry', 28, 'female')
print(school_obj1.name)  # dragon
print(school_obj2.name)  # jerry
'''方案4:类中针对给对象创建独有数据的函数名 专门定义了一个固定的方法'''


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 = 'python_cat'

    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能')


school_obj1 = Student('dragon', 18, 'male')
school_obj2 = Student('jerry', 28, 'female')
print(school_obj1.__dict__)
print(school_obj2.__dict__)
"""
类中的__init__方法会在类产生对象的时候自动执行
类产生对象的具体步骤
    1.先创建一个没有独有数据的空对象  {}
    2.将空对象和类括号内传入的数据一并交给__init__执行
        __init__的第一个参数就是对象本身
            __init__(obj,name,age,gender)
    3.将创建好的对象自动返回
给你提供这种方式能够减少代码的编写

ps:针对括号内第一个形参self其实就是一个普通的变量名而已
只不过该变量名将来专门接收对象的 所以给它起了个固定的名字叫self
"""

 

 

 5. 绑定方法

"""
在类中定义的函数默认都是绑定给对象使用的
    即对象来调 会自动将对象当做第一个参数传入
"""


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)


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

 

 

 

posted @ 2022-04-06 18:47  thrombus  阅读(35)  评论(0)    收藏  举报