langShift

面向對象程式設計基礎

面向對象程式設計 (OOP) 是一種基於「物件」概念的程式設計範式,物件可以包含資料和程式碼。C++ 是一種多範式語言,對 OOP 有強大的支援,而 JavaScript 使用基於原型的物件模型。

類別和物件定義

在 C++ 中,類別是建立物件的藍圖,為狀態(成員變數)提供初始值,並實作行為(成員函式)。物件是類別的一個實例。

正在加载...

建構函式和解構函式

建構函式是物件建立時自動呼叫的特殊成員函式。它們用於初始化物件的狀態。

解構函式是物件銷毀時(超出作用域或被 delete)自動呼叫的特殊成員函式。它們用於清理資源(例如,釋放動態分配的記憶體)。

正在加载...

封裝和存取控制

封裝是將資料(成員變數)和操作資料的方法(成員函式)捆綁到一個單元(類別)中,並限制對物件某些組件的直接存取。這透過存取修飾符實現:

  • public:成員可從任何地方存取。
  • private:成員只能從類別內部存取。
  • protected:成員可從類別內部和衍生類別存取。
正在加载...

基本繼承

繼承是一種機制,其中從現有類別(基底類別或超類別)建立新類別(衍生類別或子類別)。衍生類別繼承基底類別的屬性和行為,促進程式碼重用。

正在加载...

多型概念

多型(意為「多種形式」)允許不同類別的物件被視為共同基底類別的物件。在 C++ 中,多型主要透過虛擬函式指向基底類別的指標/引用實現。

正在加载...

與 JavaScript 原型鏈的比較

JavaScript 的物件模型是基於原型的,而不是傳統意義上的基於類別(儘管 ES6 類別提供了語法糖)。當你嘗試存取物件上的屬性或方法時,JavaScript 會首先直接在物件上尋找。如果找不到,它會在物件的原型上尋找,然後在原型的原型上尋找,依此類推,形成一個原型鏈

主要差異:

  • 繼承模型: C++ 使用經典繼承(基於類別),而 JavaScript 使用原型繼承。
  • 明確 vs. 隱含: C++ 繼承是明確的,帶有 classpublic/private/protected 等關鍵字。JavaScript 的原型繼承更為隱含。
  • 多型: C++ 依賴虛擬函式和基底類別指標/引用來實現運行時多型。JavaScript 由於其動態特性和原型鏈而自然實現多型。

虛擬函式機制

在 C++ 中,虛擬函式是在基底類別中宣告並由衍生類別重新定義(覆寫)的成員函式。當你透過指向基底類別的指標或引用呼叫虛擬函式時,執行哪個特定版本的函式是在運行時根據所指向或引用的物件的實際類型確定的。這稱為動態分派運行時多型

  • virtual 關鍵字: 在基底類別中將函式宣告為虛擬函式。
  • override 關鍵字 (C++11): 可選,但在衍生類別中是個好習慣,用於指示函式旨在覆寫基底類別中的虛擬函式。如果簽名不匹配,有助於捕獲錯誤。
  • 虛擬表 (vtable): 編譯器通常使用虛擬表來實作虛擬函式,虛擬表是函式指標的查找表。

練習題:

  1. 解釋 C++ 中封裝和繼承的概念。存取修飾符 (publicprivateprotected) 如何與封裝相關?
  2. C++ 中的多型是什麼,以及如何使用虛擬函式實現它?提供一個簡單的 C++ 程式碼範例,演示運行時多型。
  3. 比較和對比 C++ 的基於類別的繼承與 JavaScript 的基於原型的繼承。它們在實現面向對象原則方面的主要差異是什麼?

專案構想:

  • 使用繼承和多型在 C++ 中設計並實作一個簡單的 Shape 階層。建立帶有虛擬 calculateArea() 方法的基底類別 Shape。從 Shape 衍生 CircleRectangle 類別,每個類別都覆寫 calculateArea() 以提供其特定的實作。然後,建立一個 Shape 指標陣列,並演示對不同形狀多型地呼叫 calculateArea()