场景需求
闹市中,有一个恐怖分子手持菜刀劫持了一个人质,狙击手接到命令,必须将恐怖分子击毙,这整个流程用python模拟实现,且必须用面向对象的方式来写。
分解需求
假设将狙击手击毙恐怖分子流程分解为:狙击手将子弹装入弹夹,将弹夹装入狙击枪,拿枪对准恐怖分子,扣动扳机,恐怖分子玩完。用面向对象的思维来提取这个流程中的对象,分别为:
- 狙击手
- 恐怖分子
- 枪
- 弹夹
- 子弹
当然,你也可以将人质,恐怖分子持的菜刀这些作为对象,不过作为模拟示例,粒度没必要过细
狙击手.jpg
思路流程如下:
#_*_coding:utf8_*_
def main():
"""程序的执行流程"""
# 创建狙击手sniper
# 创建枪gun
# 创建弹夹clip
# 创建子弹bullet
# 创建恐怖分子terrorist
# 狙击手将子弹安装到弹夹中
# 狙击手将弹夹安装到枪中
# 狙击手拿起枪
# 狙击手开枪射杀恐怖分子
if __name__ == '__main__':
main()
创建对象
提取需求中的对象后,就可以来创建相应的类了:
狙击手和恐怖分子均属于人,只需建一个Person
类,枪、弹夹、子弹分别创建独立的类
# 人物类
class Person(object):
def __init__(self, name):
super(Person, self).__init__()
self.name = name
# 枪类
class Gun(object):
def __init__(self, name):
super(Gun, self).__init__()
self.name = name
# 弹夹类
class Clip(object):
def __init__(self, max_num):
super(Clip, self).__init__()
self.max_num = max_num # 表示弹夹能装的子弹数量
# 子弹类
class Bullet(object):
def __init__(self):
super(Bullet, self).__init__()
def main():
"""程序的执行流程"""
# 创建狙击手sniper
sniper = Person('狙击手')
# 创建枪gun
gun = Gun('狙击步枪')
# 创建弹夹clip
clip = Clip(15)
# 创建子弹bullet
bullet = Bullet()
# 创建恐怖分子terrorist
terrorist = Person('恐怖分子')
#...
将子弹装到弹夹中
子弹是一个独立的对象,要装到弹夹中,就必须在弹夹类中创建一个属性来保存子弹的对象,每个子弹对象表示一颗独立的子弹,而装子弹这个动作是由狙击手发起的,因此在Person
类中应新增装子弹的方法
Person
类新增方法: 装子弹
def install_bullet(self, clip, bullet):
# 将子弹装入弹夹中
clip.save_bullet(bullet)
Clip
弹夹类新增方法: 保存子弹
class Clip(object):
def __init__(self, max_num):
super(Clip, self).__init__()
self.max_num = max_num # 弹夹的最大容量
self.bullet_list = [] # 保存子弹对象的引用
def save_bullet(self, bullet):
# 将子弹存入弹夹
self.bullet_list.append(bullet)
在 main()
中调用装子弹的方法:
def main():
# ...
# 狙击手将子弹安装到弹夹中
sniper.install_bullet(clip, bullet)
狙击手将弹夹装到枪中
Person
类应新增装弹夹的方法,枪类需新增保存弹夹的方法
Person
新增方法:装弹夹
def install_clip(self, gun, clip):
# 将弹夹装入枪中
gun.save_clip(clip)
Gun
枪类新增方法:保存弹夹
class Gun(object):
def __init__(self, name):
super(Gun, self).__init__()
self.name = name
self.clip = None # 记录弹夹对象的引用
def save_clip(self, clip):
self.clip = clip
在 main()
中调用装子弹的方法:
def main():
# ...
# 狙击手将弹夹安装到枪中
sniper.install_clip(gun, clip)
测试枪、弹夹、子弹
测试往弹夹添加一些子弹,打印出弹夹、子弹和枪的相关信息
#_*_coding:utf8_*_
class Person(object):
def __init__(self, name):
super(Person, self).__init__()
self.name = name
def install_bullet(self, clip, bullet):
# 将子弹装入弹夹中
clip.save_bullet(bullet)
def install_clip(self, gun, clip):
# 将弹夹装入枪中
gun.save_clip(clip)
class Gun(object):
def __init__(self, name):
super(Gun, self).__init__()
self.name = name
self.clip = None # 记录弹夹对象的引用
def save_clip(self, clip):
self.clip = clip
def __str__(self):
if self.clip:
return '枪的信息为:%s, %s' % (self.name, self.clip)
else:
return '枪的信息为:%s, 没有弹夹' % self.name
class Clip(object):
def __init__(self, max_num):
super(Clip, self).__init__()
self.max_num = max_num # 弹夹的最大容量
self.bullet_list = [] # 保存子弹对象的引用
def save_bullet(self, bullet):
# 将子弹存入弹夹
self.bullet_list.append(bullet)
def __str__(self):
return '弹夹能装%s颗子弹,当前有%s颗子弹' % (self.max_num, len(self.bullet_list))
class Bullet(object):
def __init__(self):
super(Bullet, self).__init__()
def main():
"""程序的执行流程"""
# 创建狙击手sniper
sniper = Person('狙击手')
# 创建枪gun
gun = Gun('狙击步枪')
# 创建弹夹clip
clip = Clip(15)
# 创建子弹bullet
for i in range(6):
bullet = Bullet()
sniper.install_bullet(clip, bullet)
# 创建恐怖分子terrorist
terrorist = Person('恐怖分子')
# 狙击手将子弹安装到弹夹中
# sniper.install_bullet(clip, bullet)
# 狙击手将弹夹安装到枪中
sniper.install_clip(gun, clip)
# 测试弹夹信息
print(clip)
# 测试枪的信息
print(gun)
# 狙击手拿起枪
# 狙击手开枪射杀恐怖分子
if __name__ == '__main__':
main()
执行结果为:
弹夹能装15颗子弹,当前有6颗子弹
枪的信息为:狙击步枪, 弹夹能装15颗子弹,当前有6颗子弹
狙击手拿起枪
python
类新增方法:拿枪
class Person(object):
def __init__(self, name):
super(Person, self).__init__()
self.name = name
self.gun = None
def install_bullet(self, clip, bullet):
# 将子弹装入弹夹中
clip.save_bullet(bullet)
def install_clip(self, gun, clip):
# 将弹夹装入枪中
gun.save_clip(clip)
def hold_gun(self, gun):
# 举枪
self.gun = gun
def __str__(self):
if self.gun:
return "这是一个%s, 手持%s" % (self.name, self.gun.name)
塑造恐怖分子形象
狙击手和恐怖分子同属于Person
类,在实例化时要有所区分(简单起见,以是否有枪为区分)
def __str__(self):
if self.gun:
return "这是一个%s, 手持%s" % (self.name, self.gun.name)
else:
return "这是一个恐怖分子,正手持菜刀劫持人质"
狙击手向恐怖分子射击
射击的动作分解为:狙击手发起射击,弹夹弹出最上面的一颗子弹,子弹射向恐怖分子,恐怖分子玩完
整个射击的动作将所有类都调动起来了
#_*_coding:utf8_*_
class Person(object):
def __init__(self, name):
super(Person, self).__init__()
self.name = name
self.gun = None
def install_bullet(self, clip, bullet):
# 将子弹装入弹夹中
clip.save_bullet(bullet)
def install_clip(self, gun, clip):
# 将弹夹装入枪中
gun.save_clip(clip)
def hold_gun(self, gun):
# 举枪
self.gun = gun
def __str__(self):
if self.gun:
return "这是一个%s, 手持%s" % (self.name, self.gun.name)
else:
return "这是一个恐怖分子,正手持菜刀劫持人质"
def shoot(self, terrorist):
# 向恐怖分子发起射击
print('%s向%s射击' % (self.name, terrorist.name))
self.gun.fire(terrorist)
def game_over(self):
# 被击中,玩完了
print("%s被击中,已玩完" % self.name)
class Gun(object):
def __init__(self, name):
super(Gun, self).__init__()
self.name = name
self.clip = None # 记录弹夹对象的引用
def save_clip(self, clip):
self.clip = clip
def __str__(self):
if self.clip:
return '枪的信息为:%s, %s' % (self.name, self.clip)
else:
return '枪的信息为:%s, 没有弹夹' % self.name
def fire(self, terrorist):
# 枪从弹夹中获取一发子弹,子弹向恐怖分子发射过去
# 从弹夹取出一发子弹
bullet = self.clip.pop_bullet()
if bullet:
bullet.hit(terrorist)
else:
print('坑啊,竟然没子弹了')
class Clip(object):
def __init__(self, max_num):
super(Clip, self).__init__()
self.max_num = max_num # 弹夹的最大容量
self.bullet_list = [] # 保存子弹对象的引用
def save_bullet(self, bullet):
# 将子弹存入弹夹
self.bullet_list.append(bullet)
def __str__(self):
return '弹夹能装%s颗子弹,当前有%s颗子弹' % (self.max_num, len(self.bullet_list))
def pop_bullet(self):
# 弹出最上面的子弹
if self.bullet_list:
return self.bullet_list.pop()
else:
return None
class Bullet(object):
def __init__(self):
super(Bullet, self).__init__()
def hit(self, terrorist):
terrorist.game_over()
def main():
"""程序的执行流程"""
# 创建狙击手sniper
sniper = Person('狙击手')
# 创建枪gun
gun = Gun('狙击步枪')
# 创建弹夹clip
clip = Clip(15)
# 创建子弹bullet
for i in range(6):
bullet = Bullet()
# 狙击手将子弹安装到弹夹中
sniper.install_bullet(clip, bullet)
# 狙击手将弹夹安装到枪中
sniper.install_clip(gun, clip)
# 测试弹夹信息
print(clip)
# 测试枪的信息
print(gun)
# 狙击手拿起枪
sniper.hold_gun(gun)
print(sniper)
# 创建恐怖分子terrorist
terrorist = Person('恐怖分子')
print(terrorist)
# 狙击手开枪射杀恐怖分子
sniper.shoot(terrorist)
if __name__ == '__main__':
main()
执行结果为:
弹夹能装15颗子弹,当前有6颗子弹
枪的信息为:狙击步枪, 弹夹能装15颗子弹,当前有6颗子弹
这是一个狙击手, 手持狙击步枪
这是一个恐怖分子,正手持菜刀劫持人质
狙击手向恐怖分子射击
恐怖分子被击中,已玩完
总结
面向对象是解决现实复杂问题的良好方式,可以将复杂问题分解为由各种对象交互传递消息,从而使问题简单化
对象通常用属性来保存其他对象的引用,实现相互之间的关联