不間斷 Python 挑戰 Day 23 - 物件導向程式設計:繼承 (Inheritance)

閱讀時間約 12 分鐘
「繼承」顧名思義就是有一個或多個類別延續了某個類別的特性,就如同在人類社會裡,兒女接收了父母的財產、承襲了上代的技能、延續了前一輩的事業。在Python的語言裡,能夠繼承的特性為類別的公有屬性與方法,繼承的類別稱為子類別(child class / subclass)或衍伸類別(derived class),被繼承的類別稱為父類別(parent class / superclass)或基底類別(base class)。
繼承的好處在於子類別可以沿用父類別的公有屬性與方法,並開創屬於子類別本身的屬性與方法,在程式設計上若想設計一個功能為另一個功能的延伸,便可用繼承的方式來減少重複的程式碼,讓程式維護變得更簡單。例如,我們可以設計一個動物類別,這個類別的屬性可能預設有兩個眼睛、四隻腳,方法可能有呼吸、跑、叫、吃東西等等,接著要設計一個小狗的類別時,我們便可讓它繼承動物類別所有的屬性及方法,但可以改寫或是延伸專屬於小狗的特性,如小狗會汪汪叫,「汪汪叫」便是小狗專有的叫法;設計小鳥的類別時,屬性就要改寫成兩隻腳,方法要多一個飛行等等。

繼承方式

繼承的基本語法如下,首先要先有一個父類別ParentClass,繼承的子類別ChildClass在括號中帶入父類別的名稱。
class ParentClass():
  ...
class ChildClass(ParentClass):
  ...
例如以下範例創造一個Animal類別,並讓Dog類別繼承自Animal類別,雖然Dog類別的內容是空的,但它已經自動繼承了Animal類別裡面的eyes_num、legs_num屬性與breath()方法。
class Animal():
  def __init__(self):
    self.class_name = "動物"
    self.eyes_num = 2
    self.legs_num = 4
  def breath(self, animal):
    print(f"{animal}呼吸")
  class Dog(Animal):
    pass
dog = Dog()
print(f"{dog.class_name}有{dog.eyes_num}個眼睛、{dog.legs_num}隻腳")
dog.breath(dog.class_name)
執行結果:
動物有2個眼睛、4隻腳
動物呼吸

屬性與方法覆寫 (Override)

子類別和父類別可以有相同名稱的屬性與方法,當子類別的物件取用這些屬性或方法時,Python會從子類別開始尋找,若找不到才到父類別中尋找,因此重覆的名稱就相當於被覆寫了。在上例中,既然已經從Animal類別中衍生出Dog類別,就會希望能更明確寫出是"小狗"有2個眼睛、4隻腳,以及"小狗"呼吸,因此我們改寫以上的範例,有以下幾個觀察重點:
  • Dog類別有自己的初始化__init__()方法,因此Animal類別的__init__()方法被覆寫,若沒有其他敘述,class_name、eyes_num與legs_num屬性便無法被子類別的物件取用。
  • 若要呼叫父類別的方法,可用super()方法來引用,例如以下的super().__init__()呼叫Animal類別的初始化__init__()方法,此時Animal類別的class_name、eyes_num與legs_num屬性才能被子類別的物件取用。
  • Dog類別中有定義自己的class_name屬性,因此dog.class_name取用到的是Dog類別所定義的"小狗"。
  • Dog類別中有定義自己的breath()方法,並在該方法中呼叫Animal類別的breath()方法傳入參數,因此dog.breath()取用到的是Dog類別所定義的內容,也就是印出"小狗呼吸"。
class Animal():
  def __init__(self):
    self.class_name = "動物"
    self.eyes_num = 2
    self.legs_num = 4
  def breath(self, animal):
    print(f"{animal}呼吸")
class Dog(Animal):
  def __init__(self):
    super().__init__()
    self.class_name = "小狗"
  def breath(self, dog="小狗"):
    super().breath(dog)
dog = Dog()
print(f"{dog.class_name}有{dog.eyes_num}個眼睛、{dog.legs_num}隻腳")
dog.breath()
執行結果:
小狗有2個眼睛、4隻腳
小狗呼吸

子類別新增屬性與方法

如前面所述,子類別為父類別功能的延伸,因此子類別除了可以重覆使用父類別的公有屬性與方法外,也可以新增專屬於自己的屬性與方法。
如以下範例,Bird類別繼承自Animal類別,但改寫了Animal類別的class_name及legs_num屬性、保留了eyes_num屬性、並新增了wings_num屬性,方法除了改寫原本的breath()外,也新增了fly()方法。
class Bird(Animal):
  def __init__(self):
    super().__init__()
    self.class_name = "小鳥"
    self.legs_num = 2
    self.wings_num = 2
  def breath(self, bird="小鳥"):
    super().breath(bird)
  def fly(self):
    print(f"{self.class_name}會飛")
bird = Bird()
print(f"{bird.class_name}有{bird.eyes_num}個眼睛、{bird.legs_num}隻腳、{bird.wings_num}隻翅膀")
bird.breath()
bird.fly()
執行結果:
小鳥有2個眼睛、2隻腳、2隻翅膀
小鳥呼吸
小鳥會飛

多層繼承

繼承的類別不僅僅限於父類別與子類別這樣兩層的關係,也可以三代同堂,例如承續上個例子,可以再建立一個Poodle類別繼承自Dog類別,如此一來,Animal類別就變為祖父類別、Dog類別為父類別、Poodle類別為子類別。在Poodle類別中,我們用super().__init__()來取得Dog類別的屬性,再於Dog類別內取得Animal類別的屬性,如此一層接續一層,便可以繼承上層類別的所有屬性。breath()方法的處理方式雷同,Poodle類別的breath()方法依序呼叫了Dog類別及Animal類別的breath()方法,並一層層傳入參數,最後印出訊息。
class Poodle(Dog):
  def __init__(self):
    super().__init__()
    self.class_name = "貴賓狗"
  def breath(self):
    super().breath(self.class_name)
poodle = Poodle()
print(f"{poodle.class_name}有{poodle.eyes_num}個眼睛、{poodle.legs_num}隻腳")
poodle.breath()
執行結果:
貴賓狗有2個眼睛、4隻腳
貴賓狗呼吸

多重繼承

一個類別可以繼承自一個以上的父類別,例如貴賓狗是狗的一種,但也可以做為人類的寵物,兩者會有不一樣的行為,例如一般的狗吃肉,但做為寵物則有可能吃到罐頭,也會和主人有互動。以下範例建立了Dog和Pet類別,兩者有不一樣的eat()方法,Pet類別則又多了play()方法,並讓Poodle類別同時繼承自Dog和Pet類別,因此,它可以呼叫繼承而來的所有方法。
class Dog():
  def __init__(self):
    self.class_name = "小狗"
  def eat(self, dog):
    print(f"{dog}吃肉")
class Pet():
  def __init__(self):
    self.class_name = "寵物"
  def eat(self, pet):
    print(f"{pet}吃罐頭")
  def play(self, pet):
    print(f"{pet}玩球")
class Poodle(Pet, Dog):
  def __init__(self):
    self.class_name = "貴賓狗"
  def eat(self):
    super().eat(self.class_name)
  def play(self):
    super().play(self.class_name)
poodle = Poodle()
poodle.eat()
poodle.play()
執行結果:
貴賓狗吃罐頭
貴賓狗玩球
有一點需要注意的是,當繼承的類別順序對調,Python在尋找方法的順序也會有所不同,如上例若將Poodle類別的寫法改為:
class Poodle(Dog, Pet):
  ......
則執行結果會變成:
貴賓狗吃肉
貴賓狗玩球
也就是會優先呼叫Dog類別裡面的eat()方法。在多重繼承的情況下,若父類別們有相同的方法名稱,那繼承的順序就必須多加留意。

兄弟類別

一個父類別可以衍生出多個子類別,這些子類別之間就互為兄弟類別,可以互相存取對方的公有屬性和方法。在本節的例子中,Animal類別是Dog類別和Bird類別的父類別,所以Dog類別和Bird類別就為兄弟類別,在Dog類別中,我們新增一個friend()方法,來存取Bird類別的class_name屬性。
class Dog(Animal):
  def __init__(self):
    super().__init__()
    self.class_name = "小狗"
  def breath(self, dog="小狗"):
    super().breath(dog)
  def eat(self, dog):
    print(f"{dog}吃肉")
  def friend(self):
    print(f"{Bird().class_name}是我的朋友")
在類別外部呼叫friend()方法:
dog.friend()
執行結果:
小鳥是我的朋友

程式範例

為什麼會看到廣告
46會員
36內容數
留言0
查看全部
發表第一個留言支持創作者!
Wei-Jie Weng的沙龍 的其他內容
在類別一節中,我們可以用Student類別的實體來存取類別中的name變數、score字典、以及其中的所有方法,這些可以被類別以外的程式碼所直接存取的屬性稱為公有屬性(public attribute)、可以被類別以外的程式碼所直接呼叫的方法稱為公有方法(public method)。
大型程式的開發通常不會由一個人獨力完成,而是將程式依功能拆分成不同的函數或是類別,由不同人協力開發成各個模組,最後再將這些模組導入主程式,或是直接套用現有的模組。模組依來源可以分成三大類: Python內建的模組 外部模組,需從第三方的軟體儲存庫(如PyPI)並安裝使用 程式開發者自行開發的模組
全球公衛教授和公共教育家漢斯.羅斯林(Hans Rosling)在其著名的暢銷書「真確」中,提出了13個關於全球貧富、人口、出生/死亡率、教育、公衛等的「留意認知落差測驗」,回答的人不乏受過良好教育的專業人士,結果顯示,受測者在前12題平均只答對2題,遠不如隨機亂選的黑猩猩(如果黑猩猩會回答問題的話
到目前為止,我們所學習的都是程序性的程式設計(procedural programming),也就是程式碼是透過一連串的指令組成的程序或函數,由上而下依序執行不同的程序或是呼叫函數來完成程式的功能。 Python其實是一種物件導向的程式(object oriented programming, 簡稱
Python提供集合做為其資料結構,它就如同高中數學所學集合的概念,集合的內容一般來說是具有某種特性的事物的整體,例如考試分數及格的群體、數字1到100內的所有奇數、球箱內所有球的顏色等。因此,在一個集合中,每個元素的地位都是相同且無序,並且只能出現一次,集合和集合之間,也可以進行交集、聯集、差集等
Python依據變數有效的範圍可以區分為全域變數(Global variable)或區域變數(Local variable)。在函數內宣告的變數為區域變數,有效範圍只有在函數內,函數外部無法引用這個變數;在函數以外宣告的變數為全域變數,它的有效範圍為整個檔案,並且在函數內部也可以引用這個變數。
在類別一節中,我們可以用Student類別的實體來存取類別中的name變數、score字典、以及其中的所有方法,這些可以被類別以外的程式碼所直接存取的屬性稱為公有屬性(public attribute)、可以被類別以外的程式碼所直接呼叫的方法稱為公有方法(public method)。
大型程式的開發通常不會由一個人獨力完成,而是將程式依功能拆分成不同的函數或是類別,由不同人協力開發成各個模組,最後再將這些模組導入主程式,或是直接套用現有的模組。模組依來源可以分成三大類: Python內建的模組 外部模組,需從第三方的軟體儲存庫(如PyPI)並安裝使用 程式開發者自行開發的模組
全球公衛教授和公共教育家漢斯.羅斯林(Hans Rosling)在其著名的暢銷書「真確」中,提出了13個關於全球貧富、人口、出生/死亡率、教育、公衛等的「留意認知落差測驗」,回答的人不乏受過良好教育的專業人士,結果顯示,受測者在前12題平均只答對2題,遠不如隨機亂選的黑猩猩(如果黑猩猩會回答問題的話
到目前為止,我們所學習的都是程序性的程式設計(procedural programming),也就是程式碼是透過一連串的指令組成的程序或函數,由上而下依序執行不同的程序或是呼叫函數來完成程式的功能。 Python其實是一種物件導向的程式(object oriented programming, 簡稱
Python提供集合做為其資料結構,它就如同高中數學所學集合的概念,集合的內容一般來說是具有某種特性的事物的整體,例如考試分數及格的群體、數字1到100內的所有奇數、球箱內所有球的顏色等。因此,在一個集合中,每個元素的地位都是相同且無序,並且只能出現一次,集合和集合之間,也可以進行交集、聯集、差集等
Python依據變數有效的範圍可以區分為全域變數(Global variable)或區域變數(Local variable)。在函數內宣告的變數為區域變數,有效範圍只有在函數內,函數外部無法引用這個變數;在函數以外宣告的變數為全域變數,它的有效範圍為整個檔案,並且在函數內部也可以引用這個變數。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!