Python 自學第十天:寫在 Class 類別之前的物件導向 (OOP) 概念

要理解 class 的特性,就一定得提到物件導向 (OOP,Object Oriented Programming) 的概念。

物件導向

Class 類別

Class 類別是設計藍圖模具產品規格,它主要用來定義一個產品的特徵 (Python:變數、C#:屬性、Field) 和功能 (Python:函式、C#:方法、Method)。

每個程式的稱呼方式不太一樣。

Object 物件、Instance 實體

利用產品規格產生出來的實品,每個實品可能有特徵或功能上的不同

舉例

以下為虛擬碼 (Pseudo Code),每個程式的語法略有不同。

Class 類別是狗。因此我們要定義狗的特徵和功能。

1
2
3
4
5
6
7
8
類別 狗
品種
尺寸
顏色

吠叫()
print("汪!汪!汪!")
撒嬌()

藉由這個狗的模具產生出不同隻的狗狗 (物件、實體)。

1
2
3
4
5
6
7
8
9
10
11
12
13
lucky = 狗(馬爾濟斯, 小型犬, 白)   # 創造 lucky 這隻狗
miya = 狗(哈士奇, 中型犬, 黑白) # 創造 miya 這隻狗
print(lucky.品種)
print(Miya.品種)
if 有人闖空門
lucky.吠叫()
miya.吠叫()
if 主人回家
miya.撒嬌()

# 輸出結果:
# 馬爾濟斯
# 哈士奇

房產

Class 類別是房產。因此我們要定義房產的特徵和功能。

1
2
3
4
5
6
7
8
類別 房產
定價
售價
坪數

升值()
出租()
變賣()

藉由這個房產的產品規格產生出不同的物件/實體。

1
2
3
4
信義第一棟 =  房產(五千萬, 四千五百萬, 40)  # 創造「信義第一棟」這個房產
信義第一棟.出租()
if 信義第一棟.升值() > 一千萬
信義第一棟.變賣()

總結

簡單來說,Class 就是產品規格、Object 就是製作出來的實品。

一旦 Object 被建立了,系統才會分配記憶體空間給 Object,用來儲存它的變動過的特徵以及執行功能後產生的一些結果

靜態類別,不需要實體物件

一般的 Class,無法直接使用,必須創造一個實體後,利用實體才能呼叫屬性 (變數和函式)。

有一些 Class,不需要創造實體 (C# 中稱作靜態類別,我不知道 Python 中有沒有固定名稱?),可以直接使用 Class 名稱呼叫變數和函式

三大特性

物件導向有非常著名的三大特性:封裝、繼承、多型。

封裝

將物件的詳細執行步驟隱藏起來,就像個黑盒子一樣,使用者不需要知道運作的邏輯規則,只要知道透過什麼關鍵字,呼叫到想要的變數或函式就好。

就像我們一直使用的 print(參數),實際上我們不知道他是如何將傳入的資料,輸出到終端機上,但是我們會使用就好。

繼承

在父類別之下可以產生子類別,子類別的特徵和功能除了繼承自父類別外,還可以有屬於子類別自己獨特的屬性

例如:

1
2
3
4
5
6
哈士奇 繼承 狗
眼周有無黑色色塊
有無鴛鴦眼

偷偷跑出家門()
把肉骨頭藏起來()

多型

所謂的多型,是體現在函式上,它讓函式有更佳的適用性,而變數沒有多型。像是不同型態的物件都能使用同樣的名字呼叫函式,也都能做出相對的反應;或是使用不同個數的參數,會有不同的結果。

覆寫 Overriding

例如,如果我又另外定義一種狗,並且重新定義 吠叫()

1
2
3
4
5
6
吉娃娃 繼承 狗
神經質程度

躲起來()
吠叫()
print("尖銳地吠叫")

哈士奇和吉娃娃都可以呼叫 吠叫() 這個函式,但是產生的結果會不一樣。

1
2
3
4
5
6
7
8
二哈 = 哈士奇(哈士奇, 中型犬, 黑白)
小吉 = 吉娃娃(吉娃娃, 小型犬, 棕)
二哈.吠叫()
小吉.吠叫()

# 輸出結果:
# 汪!汪!汪!
# 尖銳地吠叫

多載 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)呢?