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

AdSense

前言

要理解 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)呢?