首页 » 编程 » Python-5.面向对象编程设计与开发 » 正文

在子类中重用父类的方法

有两种方式:指名道姓方式 和 super()

 指名道姓方式:不依赖于继承

super(): 依赖于继承

 

一、指名道姓方式

class Hero:
    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity


class Garen(Hero):
    camp = "Demacia"

    def __init__(self, nickname, life_value, aggresivity, weapon):
        # self.nickname = nickname
        # self.life_value = life_value
        # self.aggresivity = aggresivity
        # 上面注释部分为重复代码,可写为如下:
        Hero.__init__(self, nickname, life_value, aggresivity)  # 指名道姓 重用父类的方法
        self.weapon = weapon

    def attack(self, enemy):
        print("%s 正在遭受 %s 攻击..." % (enemy.nickname, self.weapon))
        Hero.attack(self, enemy)  # 指名道姓 重用父类的方法
        print("%s 生命值还有 %s" % (enemy.nickname, enemy.life_value))

        if enemy.life_value <= 0:
            print("%s 已死。" % (enemy.nickname))


class Riven(Hero):
    camp = "Noxus"


g1 = Garen("alex", 29, 30, "长枪")
r1 = Riven("jack", 40, 40)
g1.attack(r1)
g1.attack(r1)

运行结果:

jack 正在遭受 长枪 攻击...
jack 生命值还有 10
jack 正在遭受 长枪 攻击...
jack 生命值还有 -20
jack 已死。

 

二、super()

class Hero:
    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity


class Garen(Hero):
    camp = "Demacia"

    def __init__(self, nickname, life_value, aggresivity, weapon):
        # super(Garen, self).__init__(nickname, life_value, aggresivity)  # Python2里super()里要写参数
        super().__init__(nickname, life_value, aggresivity)  # Python3里super里可以不写

        self.weapon = weapon

    def attack(self, enemy):
        print("%s 正在遭受 %s 攻击..." % (enemy.nickname, self.weapon))
        # super(Garen, self).attack(enemy) # Python2里super()里要写参数
        super().attack(enemy)  # Python3里super里可以不写
        print("%s 生命值还有 %s" % (enemy.nickname, enemy.life_value))

        if enemy.life_value <= 0:
            print("%s 已死。" % (enemy.nickname))


class Riven(Hero):
    camp = "Noxus"


g1 = Garen("alex", 29, 30, "长枪")
r1 = Riven("jack", 40, 40)
g1.attack(r1)
g1.attack(r1)

运行结果:

jack 正在遭受 长枪 攻击...
jack 生命值还有 10
jack 正在遭受 长枪 攻击...
jack 生命值还有 -20
jack 已死。

 

关于super() 请注意:

它是按照mro列表的顺序进行查找的,所以说是依赖继承的,来看下面的例子;

class A:
    def f1(self):
        print("from A")
        super().f1()


class B:
    def f1(self):
        print("from B")


class C(A, B):
    pass


# 首先来看mro得到的查找顺序, 顺序为:
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
print(C.mro())

c = C()
c.f1()

最后运行结果输出为:

from A
from B

 

解释为什么:

程序由c调f1(),首先会在c找,没找到去C类找,C类中也没有,但是C是继承A,B的,所以先去A找,在A中找到了f1() 所以顺利的执行了,但是f1()下面还有一个 super().f1() , 我们知道super()是调用父类的,但是这里A没有没有继承父类啊,就算你说A继承object类,那object类也没有f1()啊,按道理应该报错的。但是这里并不是这样的,调用是从C的对象c开始的,所以就会按照C的mro列表顺序进行查找,当在A里没有找到,会按照mro列表顺序接着去B找,在B里找到了f1(),就执行了f1(), 所以最后结果 打印出了:

from A
from B

 

 

 

发表评论

验证码加载中....