物件導向中的多型、繼承概念與應用

更新於 發佈於 閱讀時間約 7 分鐘
物件導向(Object-Oriented Programming,OOP) 可以用來提高程式碼的可讀性、可維護性和可擴展性,同時還能夠促進程式碼的重用和組織。

多型 (Polymorphism)

以挖礦為例,當挖掘鑽石礦時,會獲得鑽石等物品。我們可以定義一個統一的礦物基類,並通過覆蓋其方法來確保挖掘特定礦物時會掉落相應的物品。這比傳統的 if-else 判斷方式更為簡潔,只需判斷挖掘的對象是否為礦物,無需關注具體的礦物類型。這樣的多型實現使程式碼更具靈活性和可擴展性。

多型與指標密切相關。通過改變指標來決定當前的礦物類型,指向不同的具體礦物類別(如鑽石礦或金礦),從而實現多型。利用 virtual 和 override 關鍵字,我們可以動態地選擇合適的函數實現。

純虛擬函數 (Pure Virtual Function)

在基類中聲明純虛擬函數,要求所有子類必須提供具體實現。這樣可以確保每個子類都有自己專屬的行為。

物件轉型 (Object Casting)

將衍生類別轉型為基類別是多型的一部分。我們可以利用基類別的指標操作不同類型的物件,實現通用處理。例如,一個人挖礦時,無論挖掘的是何種礦物,都會掉落相應的物品。這種方法可以省去大量的 if-else 判斷邏輯。

為什麼需要物件轉型?

物件轉型可以方便地替換為我們「想要的類型」,提高程式碼的靈活性和可重用性。

物件轉型的問題

如果將子類別轉型為基類別,而基類別中沒有相關的定義,則無法正常運行。

虛擬函數與覆蓋 (Virtual and Override)

如果基類中定義了 virtual 函數,而子類中對其進行了覆蓋(override),編譯器會在運行時自動選擇合適的子類實現。

不加 virtual 和 override 的情況

如果不使用 virtual 和 override,嘗試通過基類指標調用子類中的函數時,會出現調用基類函數的情況,導致返回不正確的結果。


提早綁定與延遲綁定 (Early Binding and Late Binding)

提早綁定

在編譯時期進行綁定,將所有函數綁定在一起。

延遲綁定

在運行時期進行綁定,允許程式在執行過程中動態綁定需要的函數定義。

沒有 virtual 的情況

使用提早綁定,直接在編譯時期綁定基類的定義。

加了 virtual 的情況

編譯器會使用延遲綁定,在運行時期動態尋找函數的定義,從而調用子類的相關函數實現。


虛擬解構函數 (Virtual Destructor)

對於具有衍生類別的物件,解構順序是從最底層子類的解構子開始,逐步釋放到最上層基類的解構子。這樣可以確保所有資源都能正確釋放,避免內存泄漏。

包含 (Inclusion)

以熔爐為例,減少同樣函數原型、不同類別、不同實作細節所造成的特殊判斷情況。例如,不同的礦物可以逐一燒成錠,這樣可以減少冗長的判斷邏輯。

問題

如果有多種類型的礦物,需要為每一種礦物編寫對應的處理邏輯。

解決方法

利用繼承和多型,只要繼承自礦物基類,並實現相應的燒製方法,就能大大減少重複的實現細節。


函數匹配與函數重載 (Function Matching and Function Overloading)

函數匹配

針對同名但參數不同的函數,C++ 會自動選擇對應的函數實現。例如,AddOre() 函數可以有不同的參數個數和類型,C++ 會自動匹配合適的函數。

函數重載

相同名稱但參數不同的函數。函數重載與函數匹配實現了相同的功能,使得同一個操作可以對多種類型的數據進行處理。

運算符重載 (Operator Overloading)

可以重載 C++ 內建的運算符,使得物件之間可以進行相加、相減等運算。例如,玩家的移動可以通過位置(三維空間的座標 x, y, z)的相加來實現。


類別模板 (Class Template)

使用模板讓類別使用通用型別,並將類別中通用型別變成指定型別。這樣可以避免為每種礦物創建不同的類別,而是使用模板來實現通用化。

模板綁定

通過提早綁定,在編譯時期自動綁定傳入型別的函數。


函數模板 (Function Template)

對特定函數使用通用型別 (Generic),使得函數可以處理不同型別的數據。

使用時機

根據 StackOverflow 上的專家回答,以下情況應該使用類別模板:

  • 如果某個成員的型態是 T。
  • 如果某個虛擬函數需要型別是 T。

鴨子類型 (Duck Typing)

不需要關心物件是否真的是礦物,只要能燒就可以處理。例如,木頭可以像礦物一樣燒,只要滿足最低需求即可運行。這種方式讓程式碼更具彈性。

最小需求

只要編譯能通過,無論是否符合語義,只要符合規則即可運行。


多型結論

通過抽象具體型別,變成通用處理,解決程式碼冗長的問題。

包含 (Inclusion)

減少同樣函數原型、不同類別、不同實作細節所造成的特殊判斷情況。

函數重載 (Function Overload)

相同名稱但不同參數的函數。

模板 (Template)

將不同型別的部分抽象成模板,根據使用者傳入的型別進行替換。


組合與全釋放 (Composition and Aggregation)

成員內具有其他類別成員,這個類別擁有「類別成員」的所有權。建構子或 Setter 中設定這些成員。例如,不同的食材組合可以創造不同的炒飯。當物件被解構時,所有成員都會被釋放。

組合的優點

  1. 維護方便。
  2. 新增道具簡單直觀。
  3. 擴展性好,只需新增類別即可。

組合的解構

成員內的所有成員都會被釋放。由於物件擁有其成員,當物件被解構時,其成員也應一同被釋放。


物件委派與聚合 (Delegation and Aggregation)

物件委派

組合可以實現類似「委派」的功能。例如,將裝備丟到附魔台中進行附魔。

物件的聚合

組合內的成員不會全部釋放。玩家有附魔台,裝備丟進去附魔,但附魔台消失時,裝備不會消失。委派是附魔的動作,組合是將附魔台和裝備結合。

介面

通過純虛擬函數和繼承實現「介面」,讓所有會攻擊玩家的對象都繼承一個介面,並讓子類實現細節。


耦合 (Coupling)

描述改變某些東西時造成的影響程度。

高耦合度

程式碼重複度低,但繼承鏈很長。

低耦合度

程式碼會重複,但繼承鏈短,維護方便。


組合與介面解決繼承問題

以怪物繼承為例,將重複的程式碼提到父類以提升程式碼整潔度,但容易增加耦合度。

傳統的類別繼承

將重複的程式碼提到父類以提升程式碼整潔度,但容易增加耦合度,導致維護困難。

新的繼承方式

不繼承 Mob,而是將 Mob 當成類別成員。初始化這些類別後,依然保有 Mob 的特性,通過組合與介面取代繼承類別。


The Diamond Problem

地獄幽靈和終界龍都繼承 Mob 的成員和函數,可能導致編譯時期的重複。可以利用組合與介面解決這個問題。

依賴注入 (Dependency Injection)

在建構子中將類別作為參數,根據傳入的物件做出對應行為。例如,熔爐丟肉燒會飄香,丟礦石燒得較慢。

結論

組合與介面解決繼承問題,扁平化繼承鏈,降低耦合度,更易於維護。

avatar-img
14會員
12內容數
歡迎來到我的部落格!這裡是個佛系經營的角落,我會在這裡分享我的學習及心路歷程,及不定時生活大小事分享,包括科技、閱讀、星座、金融、好物等。 希望分享的內容能夠幫助大家,與大家一同學習成長,無論是知識的豐富還是心靈的提升。歡迎留言、討論,分享你的看法和經驗。如文章內容有誤,請不吝指教,我會虛心接受並改進! 什麼都發~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這一章節旨在介紹 PHP 中的物件導向編程(OOP)概念。通過詳細講解類別、建構子、訪問修飾符(公開、私有、受保護)、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等概念,使讀者能夠理解和應用這些 OOP 技術來編寫更具結構性和可維護性的 PHP 代碼。
※ 工廠模式 定義: 工廠模式是一種實現了「工廠」概念的物件導向設計模式。它提供一個通用的工廠介面,將創建instance(實例)的程式碼交由子類別各自實現,並根據需求去動態地生成相應的物件。這種模式將物件的創建邏輯與使用邏輯分開,使程式碼更容易維護和擴展。 特點: 具有高度標準化和同質性的
※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
※ OPP第三大核心-多型 ※ 多型的基本定義: 多型是利用繼承的特性,讓不同的子類別可以實現相同的介面,但在呼叫這些介面的方法時會表現出不同的行為。這使得程式設計更具彈性和擴展性,避免了複雜的條件判斷式,同時促進了代碼的重用。 class Animal { makeSound() {
※ OPP(Object-oriented programming)簡介 什麼是OPP? OPP是一種軟體開發的風格方式。 是一種撰寫程式時的思考模式。 OPP的目的: 企圖將電腦世界的資料類比到現實中「物件」的概念。 將函數化的資料處理方式用類比到現實世界的互動關係,來簡化思考的難度。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
多型性(polymorphism)是物件導向中的一個重要概念,它指的是同一個方法或函式在不同的物件類別中可以有不同的行為。在 Python 中,多型性通常是通過繼承和方法重寫(method overriding)來實現的。 主要是為了不同資料類型的實體提供統一的介面,我們藉由下面的程式範例來多理解
Thumbnail
在物件導向程式設計的進階階段,學生將學習繼承、介面、抽象類別等核心概念。繼承允許類別共享屬性和方法,介面確保實現類別提供特定的方法實現,而抽象類別定義了基本結構供子類別擴展。這些知識點有助於提升程式碼的重用性、擴展性和維護性。
讓我在這篇文章總結一下前面對物件導向設計的討論,我們討論了物件導向的四個特性:繼承、抽象、多型、封裝,分析了它們的問題,並跟函數式編程的思維做比較。我們引入了與之相對應的特性:泛型、特性系統、模組化,有些特性雖然跟那四個特性很像,但在一些細微的地方有不同的詮釋,使得整體思考方式很不一樣。 「繼
所謂的多型是讓一個函式或是資料結構能擁有多個不同的類型,其中上一篇文章所談的就是參數多型(parametric polymorphism),這篇文章將繼續討論特設多型(ad hoc polymorphism)。特設多型跟泛型的差別在於:泛型函式對於所有的類型只能有一種實作,而特設多型會根據類型有不同
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這一章節旨在介紹 PHP 中的物件導向編程(OOP)概念。通過詳細講解類別、建構子、訪問修飾符(公開、私有、受保護)、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda 表達式、泛型和反射等概念,使讀者能夠理解和應用這些 OOP 技術來編寫更具結構性和可維護性的 PHP 代碼。
※ 工廠模式 定義: 工廠模式是一種實現了「工廠」概念的物件導向設計模式。它提供一個通用的工廠介面,將創建instance(實例)的程式碼交由子類別各自實現,並根據需求去動態地生成相應的物件。這種模式將物件的創建邏輯與使用邏輯分開,使程式碼更容易維護和擴展。 特點: 具有高度標準化和同質性的
※ 單例模式介紹 ※ 定義:單例模式是一種設計模式,確保一個class(類)只有一個實例,並提供一個存取它的全域存取點。無論如何取值,皆只對這個實例取值。 ※ 目的:保證一個類別只會產生一個物件,而且提供存取該物件的統一方法。 ※ 講解:單例模式確保一個類無論怎麼 new 或 get,都只能拿
※ OPP第三大核心-多型 ※ 多型的基本定義: 多型是利用繼承的特性,讓不同的子類別可以實現相同的介面,但在呼叫這些介面的方法時會表現出不同的行為。這使得程式設計更具彈性和擴展性,避免了複雜的條件判斷式,同時促進了代碼的重用。 class Animal { makeSound() {
※ OPP(Object-oriented programming)簡介 什麼是OPP? OPP是一種軟體開發的風格方式。 是一種撰寫程式時的思考模式。 OPP的目的: 企圖將電腦世界的資料類比到現實中「物件」的概念。 將函數化的資料處理方式用類比到現實世界的互動關係,來簡化思考的難度。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
多型性(polymorphism)是物件導向中的一個重要概念,它指的是同一個方法或函式在不同的物件類別中可以有不同的行為。在 Python 中,多型性通常是通過繼承和方法重寫(method overriding)來實現的。 主要是為了不同資料類型的實體提供統一的介面,我們藉由下面的程式範例來多理解
Thumbnail
在物件導向程式設計的進階階段,學生將學習繼承、介面、抽象類別等核心概念。繼承允許類別共享屬性和方法,介面確保實現類別提供特定的方法實現,而抽象類別定義了基本結構供子類別擴展。這些知識點有助於提升程式碼的重用性、擴展性和維護性。
讓我在這篇文章總結一下前面對物件導向設計的討論,我們討論了物件導向的四個特性:繼承、抽象、多型、封裝,分析了它們的問題,並跟函數式編程的思維做比較。我們引入了與之相對應的特性:泛型、特性系統、模組化,有些特性雖然跟那四個特性很像,但在一些細微的地方有不同的詮釋,使得整體思考方式很不一樣。 「繼
所謂的多型是讓一個函式或是資料結構能擁有多個不同的類型,其中上一篇文章所談的就是參數多型(parametric polymorphism),這篇文章將繼續討論特設多型(ad hoc polymorphism)。特設多型跟泛型的差別在於:泛型函式對於所有的類型只能有一種實作,而特設多型會根據類型有不同