面向对象前戏

发布时间 2023-03-23 10:18:05作者: 吴仁耀

前言

面向对象对于初学者而言是一个非常抽象的东西,直接讲解晦涩难懂,浅尝辄止!
在讲面向对象之前我们用一个简单的人狗大战来引入这个概念,让人可以更加直观的感受到什么是面向对象编程

人狗大战

  • 就是用代码编写一个简单的小游戏,人跟狗可以互相攻击,这里我们用字典记录数据值

推导步骤1:模拟事物

"""推导步骤1:代码定义出人和狗"""
# 一个字典表示一人或一狗
dog1 = {
     'name': '小黑',   
     'type': '田园犬',  
     'attack_val': 30,
     'life_val': 200
 }
person1 = {
     'name': '小龙',
     'type': '猛男',
     'attack_val': 10,
     'life_val': 1000
 }

PS:这里我们不难发现,频繁进行重复的操作不够方便,我们会想到使用函数封装功能,因此有了第二个阶段

推导步骤2:函数封装

"""推导步骤2:将产生人和狗的字典封装成函数并封装人和狗的攻击函数"""
def get_person(name, gender, age, t_type, attack_val, life_val):
  	 '''创建人的函数'''
     data_dict = {
         'name': name,
         'gender': gender,
         'age': age,
         '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,
         'type': t_type,
         'attack_val': attack_val,
         'life_val': life_val
     }
     return data_dict

人和狗的数据模拟问题解决了,接下来就应该干仗了,让两者都具备攻击的能力,截至目前位置我们已经养成了条件反射,谈到所谓的具备某项功能、某种能力其实都可以用函数来模拟

推导步骤3:攻击能力

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']))

推导步骤4:皇城PK

人和狗的数据有了,各自攻击的功能也有了,接下来就可以一较高下了

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)
# 狗咬人
dog_attack(dog2,p1)
print(p1)
# 人揍狗
person_attack(p2, dog1)
print(dog1)

推导步骤5:黑白颠倒

我们模拟的数据与功能彼此是独立的,也就意味着攻击的函数双方可以随意调用

'''人调用了狗的攻击动作'''
dog_attack(p1, dog1)
'''狗调用了人的攻击工作'''
person_attack(dog2,p2)

推导步骤6:数据与功能绑定

我们想让人和狗各自只能调用各自攻击的功能>>>:函数嵌套

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'), 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):
        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)

总结:思想升华

上述操作其实就是将数据与功能进行绑定,不再是所有的数据都可以调用任意的功能,而这一操作其实就是面向对象的编程思想

编程思想

我们平时听到的面向对象本质其实是一种编程思想大致可以分为两种

  • 面向过程编程
  • 面向对象编程

编程思想之面向过程编程

过程即流程,面向过程就是按照固定的流程解决问题,将程序的执行流程化,即分步操作,分步的过程中解决问题。

eg:截止ATM为止 使用的几乎都是面向过程编程
注册功能 登录功能 转账功能
上述功能都需要列举出每一步的流程,并且随着步骤的深入,问题的解决越来越简单。

ps:过程可以理解成是流水线,面向过程编程可以理解成是在创建一条流水线。我们先提出问题,然后制定出该问题的解决方案

编程思想之面向对象编程

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

# eg:
	"""人狗大战中对数据和功能的整合   可以称之为面向对象编程"""
        """模块文件内含有数据和功能函数   可以称之为面向对象编程"""
  ...

仔细的想想会发现python中一切皆对象>>>:都是数据和功能的整合

# eg:
	'''数据类型:含有数据和对应的内置方法(函数)'''
  '''文件对象:含有数据和对应的内置方法(函数)'''
  ...

image
如果把”数据“比喻为”睫毛膏“、”眼影“、”唇彩“等化妆所需要的原材料;把”功能“比喻为眼线笔、眉笔等化妆所需要的工具,那么”对象“就是一个彩妆盒,彩妆盒可以把”原材料“与”工具“都装到一起。

如果我们把”化妆“比喻为要执行的业务逻辑,此时只需要拿来一样东西即可,那就是彩妆盒,因为彩妆盒里整合了化妆所需的所有原材料与功能,这比起你分别拿来原材料与功能才能执行,要方便的多