延續前一天章節內容今天要來說繼承
,在昨日結尾時有提到 Python 為物件導向程式設計 Object-oriented programming (OOP) 中,是非常重要的。
繼承主要功用就是讓共同的功能寫在上層類別中,這樣一來就不需要在每一層都寫一樣的邏輯,也可以說如果是只需做一遍的事,不需要再做第二遍。
舉個例子:
想像一下每個角色有不同的功能
從上述例子可以發現三個角色的共通點是『會攻擊』,如果沒有使用繼承的話,會需要在三個角色定義時都做一次『會攻擊』的功能,實際上這樣是沒問題的!但會發現重複的程式碼問題存在,如果要加入新角色那麼『攻擊』這個功能就會一直重複出現,這樣容易造成後續維護上的困難,也違反了身為工程師的理念 能躺就不坐,能坐就不站 XD
實際上是違反了Don't Repeat Yourself
(DRY)原則。
class Hero:
def attack(self):
return "勇者攻擊。"
def defend(self):
return "勇者防禦。"
class Mage:
def attack(self):
return "法師攻擊。"
class Monster(self):
def attack(self):
return "怪物攻擊。"
def drop(self):
return "怪物掉寶。"
在 Python 中要讓一個類別繼承另一個類別,只需要在定義類別時在後方括號中指定『父類別』即可。
class 父類別:
# 屬性&方法
pass
class 子類別:
# 可直接使用父類別的屬性和方法
pass
回到上方角色例子調整後可以像是以下方式:
class Character:
def __init__(self, name):
self.name = name
def attack(self):
print(f"{self.name}發動了攻擊。")
class Hero(Character):
def defend(self):
print(f"{self.name}進行防禦。")
class Mage(Character):
def cast_spell(self):
print(f"{self.name}發動魔法攻擊。")
class Monster(Character):
def drop(self):
print(f"{self.name}掉寶啦。")
使用方式:
hero = Hero("戰士萊歐斯")
mage = Mage("法師瑪露希爾")
monster = Monster("怪物走路菇")
hero.attack()
hero.defend()
這樣可以看到不同角色原本需要重複撰寫『會攻擊』這個功能,透過繼承後不需要再各自類別中撰寫相同程式碼,提升可讀性及可維護性,在這邊Character
類別就是屬於『父類別』因此『子類別』繼承後就可以使用父類別的內容。
有時候我們會想讓『子類別』重新定義『父類別』的方法,只要記住在『子類別』中定義相同名稱的方法就可以覆寫『父類別』的方法。
class Character:
def __init__(self, name):
self.name = name
def attack(self):
print(f"{self.name}進行普攻。")
class Hero(Character):
def attack(self):
print(f"{self.name}揮劍攻擊。")
hero = Hero("戰士萊歐斯")
hero.attack()
# 戰士萊歐斯揮劍攻擊。
有時並不是要完全取代『父類別』的方法,只是想在原本的架構上額外增加功能,這時可以使用super()
呼叫『父類別』的方法,這樣做可避免重複的程式碼並保持『父類別』的邏輯。
class Character:
def __init__(self, name):
self.name = name
def attack(self):
print(f"{self.name}發動了普通攻擊!")
class Hero(Character):
def attack(self):
super().attack() # 呼叫父類別的 attack
print(f"{self.name}揮劍攻擊!")
hero = Hero("戰士萊歐斯")
hero.attack()
# 戰士萊歐斯發動了普通攻擊!
# 戰士萊歐斯揮劍攻擊!
在 Python 中是允許一個類別同時繼承多個『父類別』的,但要小心多重繼承容易造成**方法衝突(method resolution order, MRO)**的問題。
class Bird:
def fly(self):
print("我會飛。")
class Fish:
def swim(self):
print("我會游泳。")
class Duck(Bird, Fish):
pass
duck = Duck()
duck.fly()
duck.swim()
# 我會飛。
# 我會游泳
那麼今天就介紹到這,明天見ㄅㄅ!