🚀 物件導向程式設計 (OOP):Option D 學習筆記

歡迎來到物件導向程式設計的世界!別擔心,這個名字聽起來雖然深奧,但它其實是一種非常強大的程式碼組織方式,能讓大型軟體專案變得更好管理、更容易重用,且更易於維護。

在本章中,我們將不再把程式視為一長串的指令清單(程序導向程式設計),而是將其視為一組互相作用的「事物」或物件 (Objects)。這種思維方式是現代軟體開發的核心,因此對於你的 IB 考試和未來的程式設計之路來說,精通它是至關重要的!


1. 基礎:類別 (Classes) 與物件 (Objects)

類別與物件有什麼區別?

這是 OOP 最關鍵的起點。你必須弄清楚「藍圖」與「根據藍圖蓋好的房子」之間的差別。

1.1 類別 (Class):藍圖

  • 類別 (Class) 是一個範本、一張藍圖,或是對某種特定物件的定義。
  • 它定義了該類別的物件會包含哪些資料(屬性)以及可以執行哪些動作(方法)。
  • 類比:就像一個餅乾模具。它定義了形狀,但它本身並不是餅乾。

1.2 物件 (Object):實例 (Instance)

  • 物件 (Object) 是類別的真實、具體實例。
  • 它是根據類別定義在電腦記憶體中建立出來的。
  • 從類別建立物件的過程稱為實例化 (Instantiation)
  • 類比:使用模具烤出來的一片片餅乾。每一片餅乾都是一個獨立的物件。

範例:
如果我們有一個名為 Car(汽車)的類別,我們可以從中建立多個物件(實例):
- 物件 1:myCar(紅色、時速 60 英里、Model X)
- 物件 2:yourCar(藍色、時速 85 英里、Model Y)

重點總結:

類別決定了結構;物件則是程式中真實運作的實體。


2. 物件的剖析:狀態與行為

OOP 中的每個物件都由兩部分定義:

2.1 狀態 (State / Attributes / Data)

狀態定義了物件所擁有的特徵或資料欄位。這些通常被稱為屬性 (Attributes)實例變數 (Instance variables)

  • 範例:對於一個 Dog(狗)物件,屬性可能包含:顏色、品種和年齡。
2.2 行為 (Behavior / Methods)

行為定義了物件可以做什麼。這些是透過方法 (Methods)(在類別內定義的函式)來實現的。

  • 範例:對於一個 Dog(狗)物件,方法可能包含:bark()(吠叫)、run()(奔跑)或 eat()(進食)。
2.3 建構子 (Constructors)

建構子 (Constructor) 是一種特殊的方法,當物件被實例化時會自動呼叫。它的主要工作是設定新物件的初始狀態(初始化屬性)。

  • 類比:當你購買一支新手機(實例化物件)時,建構子就是設定過程——設定語言、時區和初始配置(狀態)。
2.4 訊息傳遞 (Message Passing)

物件之間透過傳遞訊息 (Messages) 進行互動。在 OOP 術語中,「傳遞訊息」是指呼叫另一個物件的方法。

  • 範例:如果物件 A 需要物件 B 執行某個動作,物件 A 就會呼叫物件 B 的方法。

常見錯誤:別把屬性和方法搞混了。屬性是名詞(資料);方法是動詞(動作)。


3. OOP 的四大支柱

這四大原則是物件導向程式設計的骨幹,理解它們對於 HL 考試至關重要。

3.1 封裝 (Encapsulation)

定義:

封裝 (Encapsulation) 是將資料(屬性)和操作該資料的方法綑綁在一起,形成一個單一單位(類別),並限制對該物件部分組件的直接存取。

類比:想像一顆藥囊。藥物(資料)被安全地包在殼(類別)內。你只能透過殼上的指示(方法)與藥物互動,例如「配水吞服」。

資訊隱藏 (Information Hiding):

封裝的一個關鍵面向是資訊隱藏。我們透過將屬性設為私有 (Private) 來保護物件的內部狀態,然後提供公開的方法(稱為 **Getter** 和 **Setter**,或稱存取器與修改器)來讀取或修改私有資料。

  • 為什麼要這麼做? 這樣可以防止外部程式碼不小心破壞資料。如果客戶的銀行餘額不能為負數,'withdraw'(提款)方法可以在變更私有餘額屬性之前檢查金額是否足夠。

重點複習:
封裝 = 綑綁 + 保護。
它確保了物件的內部運作機制是隱密的,且只能透過受控的方式進行存取。

3.2 繼承 (Inheritance)

定義:

繼承 (Inheritance) 是類別間獲取彼此屬性(屬性和方法)的機制。這實現了程式碼的重用,並建立了層級關係。

類比:族譜。子類別繼承了父類別的特徵。子類別不需要重新定義繼承來的特徵,但可以新增或修改既有的內容。

術語:
  • 原始類別稱為父類別 (Parent Class)超類別 (Superclass)基底類別 (Base Class)
  • 新類別稱為子類別 (Child Class)衍生類別 (Subclass)衍生類別 (Derived Class)
好處:

繼承遵循 DRY 原則:Don't Repeat Yourself(不要重複自己)。如果 DogCat 都需要 eat() 方法和 age 屬性,我們只需在 Animal 超類別中定義一次,兩個子類別就能共同繼承它們。

3.3 多型 (Polymorphism)

如果一開始覺得這部分很難也別擔心——多型(意思是「多種形式」)的核心在於靈活性和定義標準化介面。

定義:

多型 (Polymorphism) 允許將不同類別的物件視為同一類型的物件(它們的超類別),並讓單一操作(方法呼叫)根據物件實際所屬的類別產生不同的行為。

類比:「啟動引擎」的功能。無論你對「柴油卡車」物件還是「混合動力車」物件呼叫「啟動引擎」,所需的動作是一樣的(啟動引擎),但底層的執行細節(引擎實際啟動的方式)卻截然不同。

關鍵機制:方法覆寫 (Method Overriding)

這是 IB 中最常見的多型形式。如果子類別擁有與超類別相同的方法簽章(名稱和參數),子類別的版本將會取代超類別的版本執行,這稱為方法覆寫 (Method Overriding)

  • 範例: 超類別 Animal 有一個 makeSound() 方法,輸出「噪音」。子類別 Cow 覆寫了 makeSound() 輸出「哞」。當你對一個 Cow 物件呼叫 makeSound() 時,你會得到「哞」。

3.4 抽象 (Abstraction)

定義:

抽象 (Abstraction) 是只向外界展示必要資訊,同時隱藏背景實作細節的過程。它專注於物件「做什麼」,而不是它是「如何達成」的。

類比:開車。你與油門和方向盤互動(必要的介面)。你不需要理解內燃機、燃油噴射和差速齒輪的複雜物理原理也能開車。這些複雜的細節都被隱藏(抽象化)了。

抽象 vs. 封裝:

它們相關但截然不同:

  • 封裝是一種機制(使用私有變數和方法),確保實作過程整潔且安全。
  • 抽象是一種概念或目標——它呈現給使用者的是簡化且必要的觀點。

你知道嗎?
抽象正是為什麼程式設計師可以使用複雜函式庫(例如圖形函式庫)而無需閱讀數千行原始碼的原因。他們只需要知道抽象介面所定義的必要方法和參數即可。


🎉 結論與複習

你現在已經掌握了 OOP 的核心原則!記住,OOP 的設計初衷就是模擬現實世界,這就是為什麼當你開始以現實生活中的實體來思考時,類別、物件和繼承結構會變得非常直觀。

這裡有一個最終的記憶口訣,幫助你記住四大支柱:

A P I E (抽象 Abstraction, 多型 Polymorphism, 繼承 Inheritance, 封裝 Encapsulation)

快速概念檢查清單:
  • 類別 (Class) 是藍圖,定義了屬性(狀態)和方法(行為)。
  • 物件 (Object) 是類別的實例,透過建構子 (Constructor) 建立。
  • 封裝 (Encapsulation) 隱藏資料(使用私有屬性)並透過公開方法提供受控的存取權。
  • 繼承 (Inheritance) 允許子類別重用並擴充超類別的程式碼。
  • 多型 (Polymorphism) 允許物件對相同的方法呼叫做出不同的反應(通常透過方法覆寫)。
  • 抽象 (Abstraction) 只向使用者展示必要的功能,隱藏複雜性。

繼續練習在程式碼中定義這些概念。你一定沒問題的!