【C++ 筆記】資料抽象與 ADT - part 25
【C++ 筆記】資料抽象與 ADT - part 25
很感謝你點進來這篇文章。
你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!
簡介
Data abstraction refers to providing only essential information about the data to the outside world, ignoring unnecessary details or implementation.
From GeeksForGeeks
資料抽象指的是只提供外界所必要的資訊,忽略不必要的細節或實作面。
什麼意思呢?就像你在玩遊戲時,可以看到角色的 HP、MP 等資訊,但你不需要知道這些數值是怎麼計算的、存在哪個記憶體位址、或者用什麼資料結構去記錄這些資訊。
遊戲開發者只會讓你看到角色的重要狀態資訊,而把它的具體表示方法(如 class 的欄位、加密編碼或計算過程)藏起來,這就是資料抽象。
資料抽象的優點
簡化:
前面有說到資料抽象可以隱藏內部實作細節,只提供必要的介面,讓程式設計易懂、易管理。user 不用去關心物件如何運作,只需透過公開的介面使用功能。
程式碼的可維護性:
因為內部實作細節被封裝起來,修改類別的內部結構或演算法時,只要保持介面不變,外部 user 的程式碼不需改動,減少了維護成本和錯誤風險。
保護資料完整性:
將資料成員設為 private,防止外部直接修改,避免因誤用導致物件狀態不一致或錯誤,提升程式的安全性和穩定性。
可使程式碼重複使用:
資料抽象使得類別設計更具模組化,可以在不同專案或上下文中重複使用相同的抽象類別或介面,提高開發效率。
標頭檔也有資料抽象
如 <algorithm> 裡面的 sort(),不需要知道他是用什麼排序法去寫的,你只要呼叫這個函式,參數填一填,他就可以用了。(菜鳥教程)
另外一個例子是 <cmath>,裡面的 pow() 函式,也不用知道中間演算的過程,反正呼叫這函式就可以用了。(GeeksForGeeks)
封裝與抽象
兩者概念很像,但實際上還是有差別。
抽象只是程式設計的設計概念,而封裝是實現抽象的技術手段(如用存取修飾子控制外部權限存取)。
資料抽象之實作方式
當然就是使用 class 了,class 將資料(成員變數)和操作資料的函式(成員函式)封裝在一起,並透過存取修飾詞(public、private、protected)控制外部對資料的存取權限。
- public:公開介面,外部程式可以存取。
- private:私有成員,外部無法直接存取,隱藏實作細節。
- protected:受保護成員,僅限類別本身及其衍生類別存取。
在此之前,要再說明一個觀念是 ADT(Abstraction Data Type),資料抽象型態,在 C++ 中的類別都是屬於 ADT 的實作。
An Abstract Data Type (ADT) is a conceptual model that defines a set of operations and behaviors for a data structure, without specifying how these operations are implemented or how data is organized in memory.
From GeeksForGeeks
資料抽象型態是一種概念模型,為資料結構定義了一組操作和行為,而不指定這些操作如何實現或資料如何在記憶體中組織。
以下有兩個例子,都同屬於 AD、ADT 的範疇:
1 | // account.cpp |
1 | // door.cpp |
首先資料抽象在哪:
- account.cpp:user 可用 deposit()、withdraw()、getBalance() 成員函式,而不需要知道 balance 是如何運作的。
- door.cpp:user 可用 open()、close() 成員函式去控制門的開關,不用知道 isOpen 他是什麼 bool 變數,怎麼運作的等等。
上述的 balance、isOpen 都用到 private 存取修飾子控制權限,只有 class 內部可以使用,外部無法存取。
那 ADT 呢?
根據 ADT 的定義,在上述兩個範例中有以下 ADT 的 features:
- 定義一組資料:有 balance、isOpen。
- 定義一組操作:deposit()、withdraw()、getBalance()、open()、close()。
- 隱藏實作細節:透過封裝的方式讓 user 無法直接操作資料,只能透過介面(像是由開發者所提供的成員函式 deposit() 等)去操作。
- 資料結構的獨立性:就算用不同資料結構去做這些事情,介面一樣不會變。
:::info
ADT features:
- Abstraction(抽象)
- Better Conceptualization(更佳的概念化)
- Robust(茁壯性,程式能有效捕捉到錯誤)
- Encapsulation(封裝)
- Data Abstraction
- Data Structure Independence
- Information Hiding
- Modularity(模組化)
From GeeksForGeeks
:::
ADT 的經典例子
那些常見的資料結構如:
- 鏈結串列 list
- 堆疊 stack
- 佇列 queue
同屬於 ADT。
這邊就舉 stack 跟 queue 當例子,why?因為實作起來比較簡單,我恨 list。
1 | // stack.cpp |
1 | // queue.cpp |
總結
資料抽象(Data Abstraction)概念
資料抽象是指只向外界提供必要的資料資訊,隱藏不必要的細節和實作方式。如遊戲中玩家只看到角色的HP、MP 等狀態,不用知道這些數值如何計算或存放在記憶體的哪裡。開發者透過類別(class)封裝內部資料與操作,並只公開必要的介面給使用者,達成資料抽象。
資料抽象的優點
- 簡化程式設計:隱藏內部實作細節,只暴露必要介面,讓使用者專注於功能使用,讓程式可讀性提升也好管理。
- 提高可維護性:內部實作可變更而不影響外部使用者,只要介面不變,減少維護成本與錯誤風險。
- 保護資料完整性:將資料成員設為 private,避免外部直接修改,防止狀態不一致或錯誤,提升安全性與穩定性。
- 促進程式碼重用:抽象類別設計模組化,能在不同專案或上下文中重複使用,提高開發效率。
封裝與抽象的關係
抽象是設計概念,強調「做什麼」而非「怎麼做」。
封裝是實現抽象的技術手段,利用存取修飾子(public、private、protected)控制資料存取權限,隱藏實作細節。
抽象資料型態(Abstract Data Type, ADT)
ADT 是一種概念模型,定義一組資料和操作行為,但不規定其內部實作或資料組織方式。C++ 中的類別都是屬於 ADT 的實作。ADT 的特性包括:
- 定義資料集合(如 balance、isOpen)
- 定義操作行為(如 deposit()、withdraw()、open()、close())
- 隱藏實作細節,使用者只能透過介面操作資料
- 資料結構獨立性,內部實作可變更但介面不變。
ADT 的經典例子含鏈結串列(list)、堆疊(stack)、佇列(queue)等。
參考資料
單元二 資料抽象化 Data Abstraction - HackMD
Data Structure 資料結構 - Abstraction 抽象化 | by Fion Yu | Minds | Medium
Abstract Data Types - GeeksforGeeks


