Python 自學第十天:寫在 Class 類別之前的物件導向 (OOP) 概念
要理解 class 的特性,就一定得提到物件導向 (OOP,Object Oriented Programming) 的概念。
物件導向
Class 類別
Class 類別是設計藍圖、模具或產品規格,它主要用來定義一個產品的特徵 (Python:變數、C#:屬性、Field) 和功能 (Python:函式、C#:方法、Method)。
每個程式的稱呼方式不太一樣。
Object 物件、Instance 實體
利用產品規格產生出來的實品,每個實品可能有特徵或功能上的不同。
舉例
以下為虛擬碼 (Pseudo Code),每個程式的語法略有不同。
狗
Class 類別是狗。因此我們要定義狗的特徵和功能。
1 | 類別 狗 |
藉由這個狗的模具產生出不同隻的狗狗 (物件、實體)。
1 | lucky = 狗(馬爾濟斯, 小型犬, 白) # 創造 lucky 這隻狗 |
房產
Class 類別是房產。因此我們要定義房產的特徵和功能。
1 | 類別 房產 |
藉由這個房產的產品規格產生出不同的物件/實體。
1 | 信義第一棟 = 房產(五千萬, 四千五百萬, 40) # 創造「信義第一棟」這個房產 |
總結
簡單來說,Class 就是產品規格、Object 就是製作出來的實品。
一旦 Object 被建立了,系統才會分配記憶體空間給 Object,用來儲存它的變動過的特徵以及執行功能後產生的一些結果。
靜態類別,不需要實體物件
一般的 Class,無法直接使用,必須創造一個實體後,利用實體才能呼叫屬性 (變數和函式)。
有一些 Class,不需要創造實體 (C# 中稱作靜態類別,我不知道 Python 中有沒有固定名稱?),可以直接使用 Class 名稱呼叫變數和函式。
三大特性
物件導向有非常著名的三大特性:封裝、繼承、多型。
封裝
將物件的詳細執行步驟隱藏起來,就像個黑盒子一樣,使用者不需要知道運作的邏輯規則,只要知道透過什麼關鍵字,呼叫到想要的變數或函式就好。
就像我們一直使用的 print(參數)
,實際上我們不知道他是如何將傳入的資料,輸出到終端機上,但是我們會使用就好。
繼承
在父類別之下可以產生子類別,子類別的特徵和功能除了繼承自父類別外,還可以有屬於子類別自己獨特的屬性。
例如:
1 | 哈士奇 繼承 狗 |
多型
所謂的多型,是體現在函式上,它讓函式有更佳的適用性,而變數沒有多型。像是不同型態的物件都能使用同樣的名字呼叫函式,也都能做出相對的反應;或是使用不同個數的參數,會有不同的結果。
覆寫 Overriding
例如,如果我又另外定義一種狗,並且重新定義 吠叫()
:
1 | 吉娃娃 繼承 狗 |
哈士奇和吉娃娃都可以呼叫 吠叫()
這個函式,但是產生的結果會不一樣。
1 | 二哈 = 哈士奇(哈士奇, 中型犬, 黑白) |
多載 Overloading
同樣名稱的函式,但是參數個數不一樣。
file 物件
前一節提過的 file 物件
,就是類別的實例。主要是利用 open(檔案路徑, mode)
在傳入不同的參數時,創造 file 物件
並且回傳。
mode
是 "r"
為文字檔案,"rb"
為二進位檔案,創造出來的 file 物件
分別屬於
TextIOWrapper、BufferedReader 類別,繼承自 TextIOBase,而 TextIOBase 又繼承自 IOBase。
IOBase 中有 readlines()
、writelines()
、close()
等函式。TextIOBase 中有 read()
等函式。
後記
物件導向的概念看起來很簡單,但是實作起來困難重重,我很喜歡參考資料中,作者的前言,裡面有一段:
雖然到處都是物件,但並不是任意地將物件給 “塞” 入軟體系統內,物件導向的設計,是將問題領域 (problem domain) 的概念,呈現與對映 (mapping) 至軟體系統內,那麼,如何正確地捕捉 (capture) 問題領域的概念成為物件,就成為是軟體設計中,最為重要的技能與素養了。
期許自己和大家都能擁有這樣的技能。
參考資料:
[程式][概念] 物件導向基本概念。什麼是物件導向程式設計(OOP)呢?