面向对象,类的创建,类的方法

面向对象前戏

概要

  • 面向对象前戏之人狗大战
  • 面向对象编程思想
  • 面向对象重要理论
  • 面向对象代码实操
  • 对象的独有数据
  • 对象的独有方法

详细

人狗大战

# 编写代码简单的实现人打狗 狗咬人的小游戏(剧情需要)
"""推导步骤1:代码定义出人和狗"""
person1 = {
    'name':'jason',
    'age':18,
    'gender':'male',
    'p_type':'猛男',
    'attack_val':5000,
    'life_val':900000
}
dog1 = {
     'name': '小黑',
     'd_type': '泰迪',
     'attack_val': 100,
     'life_val': 8000
}
"""推导步骤2:将产生人字典和狗字典封装成函数,并封装人和狗的攻击函数"""
# def create_person(name, age, gender, p_type, attack_val, life_val):
#     person_dict = {
#         'name': name,
#         'age': age,
#         'gender': gender,
#         'p_type': p_type,
#         'attack_val': attack_val,
#         'life_val': life_val
#     }
#     return person_dict
# def create_dog(name, d_type, attack_val, life_val):
#     dog_dict = {
#         'name': name,
#         'd_type': d_type,
#         'attack_val': attack_val,
#         'life_val': life_val
#     }
#     return dog_dict
# p1 = create_person('jason', 18, 'male', '猛男', 8000, 99999999)
# p2 = create_person('kevin', 28, 'female', '淑女', 100, 800)
# d1 = create_dog('小黑', '恶霸', 800, 900000)
# d2 = create_dog('小白', '泰迪', 100, 800000)
# print(p1, p2)
# print(d1, d2)
# 定义出人打狗的动作 狗咬人的动作
# def person_attack(person_dict, dog_dict):
#     print(f"人:{person_dict.get('name')}准备揍狗:{dog_dict.get('name')}")
#     dog_dict['life_val'] -= person_dict.get('attack_val')
#     print(f"人揍了狗一拳 狗掉血:{person_dict.get('attack_val')} 狗剩余血量:{dog_dict.get('life_val')}")
# def dog_attack(dog_dict, person_dict):
#     print(f"狗:{dog_dict.get('name')}准备咬人:{person_dict.get('name')}")
#     person_dict['life_val'] -= dog_dict.get('attack_val')
#     print(f"狗咬了人一口 人掉血:{dog_dict.get('attack_val')} 人剩余血量:{person_dict.get('life_val')}")
# person_attack(p1, d1)
# dog_attack(d2, p2)

"""推导步骤3:全局变量都能调用,会产生数据混乱"""
# person_attack(d1, p1)
# dog_attack(p1, d2)

面向对象核心思路前戏

"""推导步骤4:时间只要人调用人的攻击动作,狗只调用狗的攻击动作》》》数据与方法的绑定"""

def get_person(name, age, p_type, attack_val, life_val):
    def attack(dog_dict):
        dog_dict['life_val'] -= person_dict.get('attack_val')
        print(f'人打狗{person_dict.get("attack_val")}血,狗剩余{dog_dict["life_val"]}')

    person_dict = {
        'name': name,
        'age': age,
        'p_type': p_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'attack': attack
    }
    return person_dict


def get_dog(name, age, d_type, attack_val, life_val):
    def attack(person_dict):
        person_dict['life_val'] -= dog_dict.get('attack_val')
        print(f'狗咬人{dog_dict.get("attack_val")}血,人剩余{person_dict["life_val"]}')

    dog_dict = {
        'name': name,
        'age': age,
        'p_type': d_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'attack': attack
    }
    return dog_dict


p1 = get_person('张三', 18, '猛男', 3000, 99999)
d1 = get_dog('黑豹', 5, '护卫犬', 2000, 888888)

p1.get('attack')(d1)

d1.get('attack')(p1)


面向对象的核心思想:数据与方法的绑定

编程思想

  1. 面向过程编程

    过程即流程 面向过程就是按照固定的流程解决问题
    eg:截至ATM为止 使用的几乎都是面向过程编程

    ​ 注册 登录 转账

    ​ 需要列举出每一步流程 并且随着步骤的深入 问题的解决越来越简单

    ​ ps:提出问题 然后指定出该问题的解决方案

  2. 面向对象编程

    对象 :即容器 数据与方法的结合体(python中一切皆对象)

    ​ eg:游戏人物

    ​ 托儿索,儿童劫,小学僧

    ​ 面向对象编程优点类似于造物主的感觉 我们只需要造出一个个对象

    ​ 至于该对象将来会如何发展跟程序员没关系 也无法控制

  3. 上述两种编程思想没有优劣之分 需要结合实际需求而定

    如果需求是注册 登录 人脸识别肯定面向过程更合适

    如果需求是游戏人物肯定是面向对象更合适

    实际上编程两种思想是相辅相成的 只不过占比可能不同

面向对象之类与对象

对象:数据与功能的结合体			对象才是核心 
类:多个对象相同数据与功能的结合体	类主要是为了节省代码
"""
一个人				对象
一群人				人类(所有人相同的特征)


一条狗				对象
一群狗				犬类(所有狗相同的特征)

现实中一般是现有对象再有类

在python中是先有类,再有对象
先定义出类,才能产生类


"""

类与对象的创建

面向对象并不是一门新的技术 但是为了很好的一眼区分 针对面向对象设计了新的语法形式
python中一定要有类 才能借助于类产生对象

1.类的语法结构
	class 类名:
        """代码注释"""
        对象公共数据
        对象公共方法
    1.class是定义类的关键字
    2.类名的命名与变量名几乎一致 但是需要首字母推荐大写用于区分
    3.数据:变量名与数据值的绑定 功能其实激素函数
    
2.类的定义与调用
	类在定义阶段就会执行类体代码 但是属于类的局部命名空间 外界无法调用
    
# 需求:清华大学学生选课系统

# 定义类

class Student:
    print('hahahaah')  # hahahaah 在定义时就会执行
    # 对象公共的数据

    school_name = '清华大学'

    # 对象公共功能
    def choice_course(self):
        print('学生选课')


# 查看命名空间

print(Student.__dict__)
print(Student.__dict__.get('school_name'))  # 清华大学
print(Student.__dict__.get('choice_course'))  # <function Student.choice_course at 0x0000020595FC9B80>
"""在面向对象中 类和对象访问数据或者功能 可以统一采用句点符"""
print(Student.school_name)  # 清华大学
print(Student.choice_course)  # <function Student.choice_course at 0x000001C9EAEE9550>

# 类的调用 产生对象
"""类名加括号就会产生对象 并且每执行一次都会产生一个全新的对象"""

obj1 = Student()  # 变量名obj1接收类名加括号之后返回值

obj2 = Student()
obj3 = Student()

print(obj1, obj2,
      obj3)  # <__main__.Student object at 0x000001614397B130> <__main__.Student object at 0x000001614397B040> <__main__.Student object at 0x000001614397B5E0>

print(obj1.__dict__, obj2.__dict__, obj3.__dict__)  # {} {} {}
# 私有数据方法一个都没有
print(obj1.school_name)  # 清华大学
Student.school_name = '野鸡大学'  # 修改公共数据
print(obj1.school_name)  # 野鸡大学
"""数据和功能 也可以统称为属性 数据》属性 功能》方法"""

对象独有数据

'''
    Author:clever-cat
    time  :2022/11/2-16:38
'''

# class Student:
# 对象公共的数据
# school_name = '清华大学'

# 对象公共的功能
# def choice_course(self):
#     print('学生选课功能')


# obj1 = Student()
# obj2 = Student()

# pycharm 并不是特别智能
"""推导流程1:每个对象手动添加数据"""
# obj1.__dict__['name'] = '张三'
# obj1.__dict__['age'] = 18
# print(obj1.name)  # 张三
# print(obj1.age)  # 18
# 如果有很多就需要填写非常多的代码

# obj2.__dict__['name'] = '李四'
# obj2.__dict__['age'] = 8
# print(obj2.name)  # 李四
# print(obj2.age)  # 8
"""推导流程2:封装成函数,减少代码重复性"""

# def init(obj, name, age):
#     obj.__dict__['name'] = name
#     obj.__dict__['age'] = age


# init(obj1, '张三', 20)
# init(obj2, '黑豹', 5)

# print(obj1.name)  # 张三
# print(obj1.age)  # 20

# print(obj2.name)  # 黑豹
# print(obj2.age)  # 5


"""推导流程3:全局变量都能调用,不好"""

#
# class Student:
#     # 对象公共的数据
#     school_name = '清华大学'
#     # 专门给学生添加独有数据的功能
#     def init(obj, name, age):
#         obj.__dict__['name'] = name
#         obj.__dict__['age'] = age
#
#     # 对象公共的功能
#     def choice_course(self):
#         print('学生选课功能')
#
#
# obj1 = Student()
# obj2 = Student()
#
# Student.init(obj1, '张三', 18)
# Student.init(obj2, '黑豹', 5)
#
# print(obj1.name)  # 张三
# print(obj1.age)  # 20
#
# print(obj2.name)  # 黑豹
# print(obj2.age)  # 5

"""推导过程4:init方法变形"""


class Student:
    # 对象公共的数据
    school_name = '清华大学'

    # 专门给学生添加独有数据的功能 类产生对象的过程中自动触发
    def __init__(self, name, age):
        self.__dict__['name'] = name
        self.__dict__['age'] = age

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')


obj1 = Student('张三', 18)
obj2 = Student('黑豹', 5)

print(obj1.name)  # 张三
print(obj1.age)  # 20

print(obj2.name)  # 黑豹
print(obj2.age)  # 5

"""推导5:变量名的修该"""


class Student:
    # 对象公共的数据
    school_name = '清华大学'

    # 专门给学生添加独有数据的功能 类产生对象的过程中自动触发
    def __init__(self, name, age):
        self.name = name  # 等于self.__dict__['name'] = name
        self.age = age  # 等于self.__dict__['age'] = age

    # 对象公共的功能
    def choice_course(self):
        print('学生选课功能')


obj1 = Student('张三', 18)
obj2 = Student('黑豹', 5)

print(obj1.name)  # 张三
print(obj1.age)  # 20

print(obj2.name)  # 黑豹
print(obj2.age)  # 5

对象独有功能

'''
    Author:clever-cat
    time  :2022/11/2-16:57
'''


class Student:
    school_name = '清华大学'

    # 专门给学生添加数据独有功能 类产生对象的过程中自动触发

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def chioce_cource(self):
        print(f'学生{self.name}正在选课')


obj1 = Student('张三', 18)
obj2 = Student('黑豹', 5)

"""
1.直接在全局定义功能 该函数就不是学生对象专属独有的功能了
def eat():
    print('吃东西')
obj1.eat = eat
print(obj1.__dict__)  # {'name': '张三', 'age': 18, 'eat': <function eat at 0x000001CFC4F29B80>}
obj1.eat()

"""
# 2.只能将函数放在类中 但是类中的函数有是对象公共的
"""定义类中的功能 默认就是绑定给对象使用的 谁来调用谁是主人公,主角"""
# Student.chioce_cource(123)  # 类调用需要自己传参数

# obj1.chioce_cource() # 对象调用会自动将对象当作第一个参数传入

obj1.chioce_cource()  # 学生张三正在选课
obj2.chioce_cource()  # 学生黑豹正在选课

# 对象查询数据值
print(obj1.name)  # 张三

# 对象修改数据值

obj1.name = '李四'  # 当点变量名存在,则修改数据
print(obj1.name)  # 李四
# 对象的新政数据值
obj1.gender = 'male'  # 当点变量名不存在,则新增数据
print(obj1.gender)  # male

# 删除数据值

del obj1.gender
print(obj1.__dict__)  # {'name': '李四', 'age': 18}

posted @ 2022-11-02 17:18  clever-cat  阅读(38)  评论(0编辑  收藏  举报