寫在之前
如果你是第一次聽說「類」 這個概念,把它單獨的作為一個名詞你可能會覺得怪怪的,總覺得前面缺少了修飾成分。其實,「類」是由 class
翻譯過來的,它對應的英文單詞是 class
。
基本概念
不論學什麼,概念都是非常重要的,想要學得某學科的語言,就必須使用相應的概念。在學「類」的時候,我們除了「類」還要知道什麼是 OOP
,即「物件導向程式設計」。所以我們先來認識幾個 「術語」,這些術語跟現實生活中的某些名字可能相像,但是代表的不同的含義。
1.問題空間
知道什麼是「問題空間」 是一個搬磚的必備基礎,我們下面來看一下《維基百科》中關於它的定義:
問題空間是問題解決者對一個問題所達到的全部認識狀態,它是由問題解決者利用問題所包含的資訊和已儲存的資訊主動構成的。
一個問題一般由三個方面來定義:初始狀態(開始時的不完全的資訊),目標狀態(你希望獲得的資訊或狀態),操作(從初始狀態到目標狀態所採取的步驟)。這三個部分加在一起定義了問題空間。
2.物件
這裡的「物件」不是你的「物件」,英文單詞是 Object
,至於為什麼翻譯成物件我們不去追究,我們需要知道的是「Python 中的一切都是物件」,不管你是字串,函式還是類,都是物件。
那你可能問了,Python 都是物件有什麼用麼?簡直是太有用了,這說明 Python 是物件導向程式設計的!
大佬們對於物件的定義相當高深:「一個物件要有自己的狀態,行為和唯一的標識;所有相同型別的物件所具有的結構和行為在它們共同的類中被定義」。大佬們的話確實有水平,但是這個定義對於初學者來說可能不太好理解。
其實簡言之,物件應該具有屬性(就是大佬們說的狀態),方法(就是大佬們說的行為)和標識,但是標識是自動就完成的,所以我們一般不用管它,所以一個物件主要就是有屬性和方法,屬性是說這個東西是什麼,方法是說這個東西能做什麼。
3.物件導向
物件導向(OOP),是現在程式設計的主流。物件導向程式設計可以看作是一種在程式中包含各種獨立且又互相呼叫的物件的思想,這個和傳統正好相反,傳統的思想主張將程式直接看作是一系列對計算機下達的指令,而物件導向程式設計中的每一個物件都應該能夠接受資料,處理資料並且能將資料傳達給其它物件,因此它們每一個都可以看作是一個小型的機器,即「物件」。
目前來說物件導向程式設計推廣了程式的靈活性和可維護性,並且在大型專案設計中廣為應用。當我們提到物件導向的時候,它不僅僅是指一種程式設計方法,更多意義上是一種程式開發方式。
4.類
在目前所流行的高階程式語言中,「類」 是必須要有的,我們先來看《維基百科》中的定義:
在物件導向程式設計中,類 (class) 是一種物件導向計算機程式語言的構造,是建立物件的藍圖,描述了所建立的物件共同的屬性和方法。
對於類更嚴格點的定義是由某種特定的後設資料所組成的內聚的包。它描述了一些物件的行為規則,而這些物件就被成為該類的例項。類有介面和結構,介面描述瞭如何通過方法與類及其例項互相操作,而結構描述了一個例項中資料如何劃分為多個屬性。
支援類的程式語言在支援與類相關的各種特性方面都多多少少有一些微妙的差異。大多數都支援不同形式的類繼承。類的出現,為物件導向程式設計的三個最重要的特性(封裝,繼承,多型)提供了實現的手段。
看到這裡,你或許有這麼一個認識,要物件導向程式設計就要用到類,雖然不是很嚴格,但是我們可以這麼說,當然了,反過來的話是不可以的。
寫 “類”
類是對某一群具有同樣屬性和方法的物件的抽象,比如長翅膀會飛的的生物,我們把它們統一稱為「鳥」。
這裡我們以「漂亮小姐姐」為例,我們要定義類,就要抽象的找出共同的方面,我們用 class 來宣告,然後後面跟著類的名字:
class 小姐姐:
pass
複製程式碼
我們在這裡先不用 Python 來寫,而是用不太像虛擬碼的方式來表示,主要是為了讓大家先了解一下什麼是什麼:
class 小姐姐:
皮膚 = 白色
髮色 = 黑色
唱歌()
跳舞()
複製程式碼
我們定義了一個叫小姐姐的類,後面沒有帶括號的是屬性,帶括號的是方法,其中的屬性和方法,預設是所以的小姐姐都具有,這個類僅僅是對小姐姐們的通常抽象,並不是指某個具體的誰誰誰。
對於一個具體的小姐姐,比如西施,她就是上面定義的小姐姐這個類的具體化,這在程式設計中稱為「小姐姐」類的例項:
西施 = 小姐姐()
複製程式碼
用上面的方式就是將「小姐姐」 類例項化了,所謂的例項,就是一個具體的東西。對於西施這個例項,就可以具體化一些屬性,比如髮色,還可以用一些具體的方法,比如唱歌,通常用「.」的方式,比如 西施.皮膚,就得到白色。
下面開始我們不用虛擬碼了,開始用真正的 Python 程式碼來了解類。
Python 是個不斷髮展的語言,於是有了 Python2 和 Python3 兩個版本,在 Python2 中,類分為「新式類」和「舊式類」,但是在 Python3 中沒有這種新舊之分,就只是 「類」而已,當然我們的用的版本還是 Python3。
建立一個 “類”
如何建立一個「類」,為了更普遍性的說明,我來寫一個具有通常類的結構的類,請看下面的例子:
class Person:
"""
具有通常類的結構的 Person 類
"""
def __init__(self,name):
self.name = name
def get_name(self):
return self.name
def get_sex(self,sex):
per_sex = {}
per_sex[self.name] = sex
return per_sex
複製程式碼
上面的 Person 類是一個很常見的類,下面我來對它就行逐一解釋:
在 Python3 中所有的類都是 object 的子類,正是因為這個原因,所以不用像 Python2 中那樣要把對 object 的繼承寫出來。
class Person
:這是在宣告建立一個名字是「Person」的類,關鍵詞是 class,就和函式的 def 一樣。類的名字按照慣例一般用大寫字母開頭,如果名字是兩個單詞,那麼兩個單詞的首字母都要大寫,比如 HotDog,當然瞭如果你不想這樣也是可以的,但是我希望你記住 “你的程式碼是給別人看的”,不要給別人和自己以後讀程式碼的時候帶來麻煩。最後當所有的一切都結束的時候,別忘了在最後帶上冒號。
接下來就是類裡面的程式碼塊,上面例子中類裡的程式碼塊看起來很熟悉,都是 def 這個關鍵詞開頭的函式。你是對的,它們就是函式,但是你仔細看一下就會發現,這些函式跟我們在前面學過的函式略微不同,它們的引數都有「self」(要注意 self 是預設的第一個引數)。這個正是類中函式的特色,是為了跟我們以前學過的函式區別開來,所以一般在類裡的函式我們不叫它們函式,而叫它們 「方法」。所以當你聽到有人說「方法」 的時候,不用奇怪,它和函式在本質上是一樣的。
下面對類裡的幾個函式做一個簡要的介紹。
def __init__(self,name)
:這是一個特殊的方法,以雙下劃線開頭和結尾,這樣的方法其實在類裡面還有很多,統一叫它們「特殊方法」。對於 __init__()
還有一個別的名字,叫「建構函式」,也有叫它是「初始化方法」 的,個人認為第二個更好一點,因為單從字面上來看,它對應的含義應該是初始化。所謂的初始化,就是讓類有一個基本的樣子,而不是裡面什麼也沒有,很多事情都要初始化,讓事情有一個具體的起點狀態,比如你要吃飯,碗裡得先有飯。在用類建立例項的時候,首先執行的是初始化方法。
在上面的例子中,初始化方法裡的引數除了 self 以外,還有一個 name,在 Person 類被例項化的同時,要傳給它一個值。self.name = name
的意思是建立例項的一個屬性,這個屬性的名字也是 name,它的值等於引數 name 所傳入的值。要注意的是,這裡的屬性 self.name
和引數 name
是純屬巧合,你也可以寫成 self.aaa = name,只不過這樣寫會覺得很彆扭。
接下來的 def get_name(self)
和 def get_sex(self,sex)
是類裡面的另外兩個方法,這兩個方法除了第一個引數必須是 self 以外,其它跟函式沒有什麼區別。你只需要注意的是,兩個方法中都用到了 self.name,屬性的這種呼叫方式只能在類裡面使用。
“類” 的例項
類是物件的定義,例項才是真實的東西。比如「人」是一個類,但是「人」 終究不是具體的某個會喘氣的,只有「rocky」才是具體的東西,但他是具有「人」 這個類所定義的屬性和方法。「rocky」就是「人」這個類的例項。
我們繼續用上面那個類的例子,直接寫一下呼叫這個類的程式碼:
if __name__ == "__main__":
boy = Person('rocky')
print(boy.name)
name = boy.get_name()
print(name)
his_sex = boy.get_sex('男')
print(his_sex)
複製程式碼
上面程式碼中 girl = Person('rocky')
是利用上面的類建立的例項。建立例項的過程就是呼叫類 Person()
,首先執行的是初始化函式,上述例子中的初始化函式有兩個引數,即 self 和 name,其中 self 是預設引數,不需要傳值,name 則需要給它傳值,所以用Person('rocky')
的樣式。
boy 就是一個例項,它有屬性和方法,self.name 是它的屬性,boy.get_name()
和 boy.get_sex('男')
是通過例項來呼叫方法。
剛才是以 boy = Person('rocky')
的方式建立了一個例項,仿照這個樣式還可以建立更多的例項,比如 girl = Person('xishi')
等,也就是說,一個類可以建立多個例項。
寫在最後
這就是通過類建立例項,並且通過例項來呼叫屬性和方法的過程,我感覺我已經說的很詳細了,希望你能認真的看完。
更多內容,歡迎關注公眾號「Python空間」,期待和你的交流。