在子类中重用父类的方法
有两种方式:指名道姓方式 和 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
共有 0 条评论