老王打枪,助于理解面向对象的一个案例

class Person(object):
    """人类"""

    def __init__(self, name):
        # 调用super的时候,要传本类的名
        super(Person, self).__init__()
        self.name = name
        self.gun = None
        self.hp = 100

    def zhuangzidan(self, dan_jia, zidan):
        # 弹夹里放子弹
        dan_jia.add_zidan(zidan)

    def zhuandanjia(self, gun, dan_jia):
        """枪里放弹夹"""
        gun.add_danjia(dan_jia)
        pass

    def get_gun(self, a_gun):
        """拿起枪"""
        self.gun = a_gun

    def __str__(self):
        if self.gun:
            return "%s的血量为%d,持枪者,枪为:%s" \
                   % (self.name, self.hp, self.gun)
        else:
            return "%s的血量为%d,无枪" % (self.name, self.hp)

    def shoot(self, emeny):
        """射击"""
        # 用枪射击
        self.gun.shoot(emeny)

    def diao_xue(self, attack):
        self.hp -= attack
        if (self.hp <= 0):
            print("%s死亡" % self.name)
        else:
            print(self)


class Gun(object):
    """枪类"""

    def __init__(self, arg):
        super(Gun, self).__init__()
        self.arg = arg  # 枪的类型
        self.danjia = None

    def add_danjia(self, dan_jia):
        """用枪保存弹夹"""
        self.danjia = dan_jia

    def __str__(self):
        # 当你去打印一个对象的时候,会自动调用__str__方法
        # 如果没有这个方法,会打印它的内存地址
        if self.danjia:
            return "枪名为:%s,%s" % (self.arg, self.danjia)
        else:
            return "枪名为:%s,无弹夹" % self.arg

    def shoot(self, emeny):
        """枪取子弹,射击"""
        # 弹夹弹出一发子弹
        zidan = self.danjia.tan_chu_zidan()
        # 判断有没有子弹,如果取到了,就攻击敌人
        if zidan:
            zidan.hurt(emeny)
        else:
            print("没有子弹了")


class DanJia(object):
    def __init__(self, max_num):
        super(DanJia).__init__()
        self.max_num = max_num  # 弹夹容量
        self.zidan_list = []  # 用于记录所有子弹的引用

    def add_zidan(self, zidan):
        """弹夹中装子弹"""
        self.zidan_list.append(zidan)

    def tan_chu_zidan(self):
        """获取最上面的一颗子弹"""
        if self.zidan_list:
            zidan = self.zidan_list.pop()
            return zidan
        else:
            return None

    def __str__(self):
        return "弹夹(%d/%d)" % (len(self.zidan_list), self.max_num)


class ZiDan(object):
    def __init__(self, arg):
        super(ZiDan, self).__init__()
        self.arg = arg  # 子弹杀伤力

    def hurt(self, emeny):
        """子弹伤害敌人,敌人掉血"""
        emeny.diao_xue(self.arg)


def main():
    """用来控制整个程序的流程"""
    pass

    # 创建老王对象
    laowang = Person("老王")
    # 创建枪对象
    ak47 = Gun("AK47")
    # 创建一个弹夹对象
    dan_jia = DanJia(20)
    # 创建一些子弹
    for i in range(15):
        zidan = ZiDan(10)
        # 老王把子弹安到弹夹中
        laowang.zhuangzidan(dan_jia, zidan)
    # 老王把弹夹安装到枪中
    laowang.zhuandanjia(ak47, dan_jia)

    # 测一下枪的功能
    print(dan_jia)
    print(ak47)
    # 老王拿枪
    laowang.get_gun(ak47)
    print(laowang)
    # 创建一个敌人
    emeny = Person("老张")
    print(emeny)
    # 老王开枪打敌人
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)
    laowang.shoot(emeny)


if __name__ == '__main__':
    """只本类才运行"""
    main()

你可能感兴趣的:(老王打枪,助于理解面向对象的一个案例)