iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
佛心分享-IT 人自學之術

Python 學習筆記系列 第 20

筆記Day20:繼承 Inheritance

  • 分享至 

  • xImage
  •  

延續前一天章節內容今天要來說繼承,在昨日結尾時有提到 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()
# 我會飛。
# 我會游泳

繼承的好處

  • 簡潔:共用的功能放在『父類別』,不需要重複撰寫。
  • 結構清楚:不同類別之間有『階層關係』。
  • 提升維護性及擴充性:修改『父類別』就能影響所有繼承的『子類別』。

那麼今天就介紹到這,明天見ㄅㄅ!


上一篇
筆記Day19:物件 Object 與類別 Class
系列文
Python 學習筆記20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言