在重载所有父类的方法时,我应该使用多态吗?

时间:2016-07-13 15:33:27

标签: python python-2.7 oop polymorphism

我正在为大学的一个模块创建一个基本的OOP程序。我正在使用python制作一个简单的CLI RPG游戏。对于几个类,我将重载所有父类的函数,我不确定在这些情况下是否应该使用多态。

示例:

class character():

def __init__(self, name, hp, level, defense, damage):
    self.hp = hp + (10 * level)
    self.name = name
    self.level = level
    self.defense = defense + (10 * level)
    self.damage = damage + (10 * level)
    self.target = None
    self.invetory = []

def attack(self, target):
    hit_chance = random.random()
    print '%s %s attacked %s %s' % (self.__class__.__name__, self.name, target.__class__.__name__, target.name)

    if self.target == None:
        self.target = target

    if hit_chance <= 0.2:
        print '%s %ss\' attack missed \n' % (self.__class__.__name__, self.name)
        return

    target.attacked(self.damage, self)
    self.fighting()

def attacked(self, wound, attacker):
    wound = wound - float(self.defense) / 100 * random.randint(30, 60)
    self.hp = self.hp - wound
    print '%s %s took %s points of damage from %s %s' % (self.__class__.__name__, self.name, wound, attacker.__class__.__name__, attacker.name)
    if self.target == None:
        self.target=attacker

    if self.hp <= 0:
        print '%s has been defeated. %s is victorious!' % (self.name, attacker.name)
        attacker.victory(self.level)
        del self
        return

    print '%s %ss\' hp fell to %s\n' % (self.__class__.__name__, self.name, self.hp)

def fighting(self):
    threading.Timer(5.0, fighting).start()
    if self.target:
        attack(self.target)
        if self.target.hp <= 0:
            self.target = None

    time.sleep(2)

class player(character):

    def __init__(self, name):
        self.level = 1
        self.max_hp = 100 + 10 * self.level
        self.hp = self.max_hp
        self.name = name
        self.defense = 10 * self.level
        self.damage = 10 * self.level
        self.target = None
        self.inventory = ['bronze_dagger']
        self.xp = 0
        self.gold = 0
        self.weapon = bronze_sword

    def victory(self, level):
        self.xp = self.xp + ((level - self.level) * 20 + random.randint(10, 50))
        self.gold = level * random.randint(1, 100)
        self.hp = self.max_hp

        if self.xp >= self.level * 100:
            self.level_up()

    def attacked(self, wound, attacker):
        wound = wound - float(self.defense) / 100 * random.randint(40, 60)
        self.hp = self.hp - wound
        print '%s %s took %s points of damage from %s %s' % (self.__class__.__name__, self.name, wound, attacker.__class__.__name__, attacker.name)

        if self.hp <= 0:
            print 'You have been defeated by %s!\nGAME OVER!' % (attacker.name)
            del self
            return

        print '%s %ss\' hp fell to %s\n' % (self.__class__.__name__, self.name, self.hp)

    def level_up(self):
        self.xp = 0
        self.level = self.level + 1
        self.hp = 100 + 10 * self.level
        self.defense = 10 * self.level
        self.damage = 10 * self.level
        print '%s %s has reached level %s!' % (self.__class__.__name__, self.name, self.level)

正如您所看到的,播放器类重载了所有字符类的函数并添加了更多函数。

1 个答案:

答案 0 :(得分:0)

是的,我不明白为什么不。这是一个好处的例子,我重构了你的代码以重新使用(查找'Python DRY')玩家和角色之间的一些常见代码,仅用于攻击。它看起来好像是更多的代码,但它允许你做的是关注Player和Character类之间的差异和共性。 2个消息方法可以使用在类级别(在Character和Player上)定义的字符串模板,并且仍然使用相同的方法(您必须使用基于字典的模板查找)。

重点是,OOP给桌子带来了很大的力量。但是,不是你最初编写这些类的方式。

class Character(object):

    defense_min, defense_max = 30, 60

    def choose_target(self, attacker):
        if self.target == None:
            self.target=attacker

    def show_hit_msg(self):
        print '%s %s took %s points of damage from %s %s' % (self.__class__.__name__, self.name, wound, attacker.__class__.__name__, attacker.name)

    def do_0_hp(self):
        if self.hp <= 0:
            print '%s has been defeated. %s is victorious!' % (self.name, attacker.name)
            attacker.victory(self.level)
            del self
            return

    def end_attack(self):
        print '%s %ss\' hp fell to %s\n' % (self.__class__.__name__, self.name, self.hp)

    def attacked(self, wound, attacker):
        wound = wound - float(self.defense) / 100 * random.randint(self.defense_min, self.defense_max)
        self.hp = self.hp - wound
        self.show_hit_msg()

        self.choose_target()
        self.do_0_hp()

        self.end_attack()                



class Player(Character):

    .....

    defense_min, defense_max = 40, 60

    def choose_target(self, attacker):
        #you dont do anything 
        pass

    def show_hit_msg(self):
        print '%s %s took %s points of damage from %s %s' % (self.__class__.__name__, self.name, wound, attacker.__class__.__name__, attacker.name)

    def do_0_hp(self):
        if self.hp <= 0:
            print 'You have been defeated by %s!\nGAME OVER!' % (attacker.name)
            del self
            return

    def end_attack(self):
        print '%s %ss\' hp fell to %s\n' % (self.__class__.__name__, self.name, self.hp)

P.S。 del self可能不会像您认为的那样工作,并且不是必需的。