繼承是一種創建類的方法,在python中,一個類可以繼承來自一個或多個父類。原始類稱為基類或超類。
class ParentClass1: pass
class ParentClass2: pass
class SubClass1(ParentClass1): pass
class SubClass2(ParentClass1,ParentClass2): pass
查看繼承:
>>> SubClass2.__bases__(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
什麼時候用繼承假如已經有幾個類,而類與類之間有共同的變量屬性和函數屬性,那就可以把這幾個變量屬性和函數屬性提取出來作為基類的屬性。而特殊的變量屬性和函數屬性,則在本類中定義,這樣只需要繼承這個基類,就可以訪問基類的變量屬性和函數屬性。可以提高代碼的可擴展性。
繼承和抽象(先抽象再繼承)抽象即提取類似的部分。基類就是抽象多個類共同的屬性得到的一個類。
class Riven: camp='Noxus' def __init__(self,nickname, script, aggressivity=54, life_value=414, ): self.nickname = nickname self.aggressivity = aggressivity self.life_value = life_value self.script=script
def attack(self,enemy): print(self.script) enemy.life_value -= self.aggressivity
class Garen: camp='Demacia' def __init__(self,nickname, script, aggressivity=58, life_value=455, ): self.nickname = nickname self.aggressivity = aggressivity self.life_value = life_value self.script = script
def attack(self,enemy): print(self.script) enemy.life_value -= self.aggressivityg1=Garen("德瑪西亞之力","人在塔在")g1.camp="諾克薩斯"
r1=Riven("瑞雯","斷劍重鑄之日,騎士歸來之時")g1.attack(r1)print(r1.life_value)
人在塔在
356
Garen類和Riven類都有nickname、aggressivity、life_value、script四個變量屬性和attack()函數屬性,這裡可以抽象出一個Hero類,裡面有裡面包含這些屬性。
class Hero: def __init__(self, nickname, script, aggressivity, life_value, ): self.nickname = nickname self.aggressivity = aggressivity self.life_value = life_value self.script = script
def attack(self,enemy): print("Hero.attack") enemy.life_value -= self.aggressivity
class Riven(Hero): camp='Noxus' def __init__(self,nickname,script,aggressivity=54,life_value=414): Hero.__init__(self,nickname,script,aggressivity,life_value)
def attack(self,enemy): print(self.script) Hero.attack(self,enemy)
class Garen(Hero): camp='Demacia' def __init__(self,nickname,script,aggressivity=58,life_value=455): Hero.__init__(self, nickname, script, aggressivity, life_value) def attack(self,enemy): print(self.script) Hero.attack(self, enemy)g1=Garen("德瑪西亞之力","人在塔在")g1.camp="諾克薩斯"
r1=Riven("瑞雯","斷劍重鑄之日,騎士歸來之時")g1.attack(r1)print(r1.life_value)
人在塔在Hero.attack
356
嚴格來說,上述Hero.init(self,…),不能算作子類調用父類的方法。因為我們如果去掉(Hero)這個繼承關係,代碼仍能得到預期的結果。
總結python中繼承的特點:
在子類中,並不會自動調用基類的init(),需要在派生類中手動調用。
在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。
先在本類中查找調用的方法,找不到才去基類中找。
繼承的好處提高代碼的復用。
繼承的弊端可能特殊的本類又有其他特殊的地方,又會定義一個類,其下也可能再定義類,這樣就會造成繼承的那條線越來越長,使用繼承的話,任何一點小的變化也需要重新定義一個類,很容易引起類的爆炸式增長,產生一大堆有著細微不同的子類. 所以有個「多用組合少用繼承」的原則。