面向对象编程

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 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):
    # 使用最简单的掉血逻辑 血量减去对方攻击力
    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):
    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)
"""人调用了狗的攻击"""
dog_attack(p1,dog1)
"""狗调用了人的攻击"""
person_attack(dog2,p2)

如何做到只有人可以调用人的攻击,狗调用狗的攻击

其实就是想让人的数据跟人的功能绑定,狗的数据跟狗的功能绑定

def get_person(name,gender,age,t_type,attack_val,life_val):
    # 将人的攻击放在产生人的函数中
    def person_attack(person_obj,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'),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):
        # 使用最简答的掉血逻辑  血量减去对方攻击力
        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)

上述操作其实就是将数据与功能进行绑定,不再是所有的数据都可以调用任意的功能

上述将数据与功能整合到一起的操作其实就是 面向对象编程思想

2.面向过程编程和面向对象编程

面向过程编程

将程序的执行流程化 即分步操作 分步的过程中解决问题

eg:注册,登录,购物车

注册:第一步获取用户名 第二部比对用户名数据...

结算:第一步获取购物车数据 第二部计算钱数...

过程可以理解是流水线,面向过程编程可以理解成是在创建一条流水线

面向对象编程

核心:对象

对象其实就是一个容器,将数据与功能整合到一起,只要符合这一描述的事物都可以称之为对象

人狗大战最后的函数内部含有数据和功能,可以称之为面向对象编程

模块文件内部含有数据和功能 也可以称之为面向对象编程

python中一切皆对象

针对面向对象编程提供了专门的语法,识别度更高,编写更精简

总结

面向过程和面向对象两者没有优劣之分,具体要结合实际情况,甚至很多时候两者是混合在一起的只不过思想占据的比例不同

3.类与对象的概念

对象

数据与功能的结合体

即类别,种类,相当于诸多对象共有的特征(数据,功能)

人>>>:对象     一群人>>>:人类

狗>>>:对象     一群狗>>>:犬类

上述中的人类和犬类就是用来描述多个对象相同特征的名词

黄种人、黑种人、白种人都属于人类,但是彼此也有不同的特征

类只能描述出公共的特征,不同的特征应该由对象自己描述

类其实也算对象>>>:一切皆对象

4.类与对象的创建

在代码编程中是先有类才能有对象

基本结构

class Student:
    # 学生类公共的数据
    school = '清华大学'
    # 学生类公共的功能
    def choose_course(self):
        print('学生选课功能’)

类体代码无需调用就会执行产生类的名称空间

语法结构

class 类名:

    类体代码

  • class是定义类的关键字
  • 类名类似于关键字 但是首字母推荐大写 用于区分
  • 类体代码就是存放对象公共数据和功能的地方

    数据:变量名 = 变量值

    功能:函数

 __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.school) # 清华大学
print(obj1.choose_course) # bound method
print(obj2.choose_course) # bound method
print(obj1.school) # 清华大学
print(obj2.school) # 清华大学
Student.school = '北京大学‘ # Student.__dict__['school'] = '北京大学’ 修改名字与值的对应关系
print(obj1.school) # 北京大学
print(obj2.school) # 北京大学

5.对象的实例化

实例化也可以理解为对象的独有属性

obj1 = Student()  # 目前对象没有自己独有的属性
obj2 = Student()  # 目前对象没有自己独有的属性
print(obj1.__dict__)  # 大白话就是给字典添加键值对
print(obj2.__dict__)  # 大白话就是给字典添加键值对

推导过程

方案1:逐步给对象添加独有的数据

obj1.__dict__['name'] = 'jason'  # obj1.name = 'jason'
obj1.__dict__['age'] = 18  # obj1.age = 18
obj1.__dict__['gender'] = 'male'  # obj1.gender = 'male'

obj2.__dict__['name'] = 'kevin'  # obj2.name = 'kevin'
obj2.__dict__['age'] = 2  # obj2.age = 28
obj2.__dict__['gender'] = 'female'  # obj2.gender = 'female'
print(obj1.__dict__,obj2.__dict__)
print(obj1.name)  # jason
print(obj2.name)  # kevin

方案2:将冗余的添加步骤封装成函数

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)
print(obj2.name)

方案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:类中针对给对象创建独有数据的函数名,专门定义了一个固定的方法

obj1 = Student('jason', 18, 'male')
obj2 = Student('kevin', 28, 'female')
print(obj1.__dict__)
print(obj2.__dict__)

类产生对象的具体步骤

类中的__init__方法会在类产生对象的时候自动执行

  1. 先创建一个没有独有数据的空对象  {}
  2. 将空对象和类括号内传入的数据一并交给__init__执行,__init__的第一个参数就是对象本身
  3. 将创建好的对象自动返回

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

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
obj = Student('zhou',18,'male') # 不传入参数会报错
print(obj.__dict__)
{'name': 'zhou', 'age': '18', 'gender': 'male'}

6.绑定方法

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

class Student:
    school = '清华大学'
    # __init__方法不要自己去调用 
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def func(self):
        print(self)
    def index(self):
        print('%s正在调用index方法'%self.name)

obj1 = Student('jason', 18)
obj2 = Student('kevin', 28)

类调用类中函数

有几个参数就需要传几个参数

对象调用类中函数

会将当前调用的对象当做第一个参数自动传入

 

 

posted @ 2022-04-06 17:06  顺溜_7  阅读(39)  评论(0编辑  收藏  举报