物件導向(上)

AA發表於2020-12-16

物件與類

在現實世界中,隨處可見的一種事物就是物件,物件是事物存在的實體,如學生、汽車等。人類解決問題的方式總是將複雜的事物簡單化,於是就會思考這些物件都是由哪些部分組成的。通常都會將物件劃分為兩個部分,即靜態部分與動態部分。顧名思義,靜態部分就是不能動的部分,這個部分被稱為“屬性”,任何物件都會具備其自身屬性,如一個人,其屬性包括高矮、胖瘦、年齡、性別等。然而具有這些屬性的人會執行哪些動作也是一個值得探討的部分,這個人可以轉身、微笑、說話、奔跑,這些是這個人具備的行為(動態部分),人類通過探討物件的屬性和觀察物件的行為來了解物件。
在計算機世界中,物件導向程式設計的思想要以物件來思考問題,首先要將現實世界的實體抽象為物件,然後考慮這個物件具備的屬性和行為。例如,現在面臨一名足球運動員想要將球射進對方球門這個實際問題,試著以物件導向的思想來解決它。步驟如下:
首先可以從這一問題中抽象出物件,這裡抽象出的物件為一名足球運動員。
然後識別這個物件的屬性。物件具備的屬性都是靜態屬性,如足球運動員有一個鼻子、兩條腿等,這些屬性如圖所示。
在這裡插入圖片描述
接著識別這個物件的動態行為,即足球運動員的動作,如跳躍、轉身等,這些行為都是這個物件基於其屬性而具有的動作,這些行為如圖所示。
在這裡插入圖片描述
識別出這個物件的屬性和行為後,這個物件就被定義完成了,然後根據足球運動員具有的特性制定要射進對方球門的具體方案以解決問題。
究其本質,所有的足球運動員都具有以上的屬性和行為,可以將這些屬性和行為封裝起來以描述足球運動員這類人。由此可見,類實質上就是封裝物件屬性和行為的載體,而物件則是類抽象出來的一個例項。這也是進行物件導向程式設計的核心思想,即把具體事物的共同特徵抽象成實體概念,有了這些抽象出來的實體概念,就可以在程式語言的支援下建立類。因此,類是那些實體的一種模型,具體如圖所示。在這裡插入圖片描述
在圖中,通過物件導向程式設計的思想可以建立現實世界中具體事物、實體概念與程式語言中類、物件之間的一一對應關係。
類的定義
Python使用class關鍵字來定義類,其語法格式如下:
在這裡插入圖片描述
其中,類名的首字母一般需要大寫,具體示例如下:
在這裡插入圖片描述
其中,例項方法與前面學習的函式格式類似,區別在於類的所有例項方法都必須至少有一個名為self的引數,並且必須是方法的第一個形參(如果有多個形參),self引數代表將來要建立的物件本身。另外,self.name稱為例項屬性,在類的例項方法中訪問例項屬性時需要以self為字首。
在類中定義例項方法時,第一個引數指定為“self”只是一個習慣。實際上,該引數的名字是可以變化的,具體如下所示:
在這裡插入圖片描述
儘管如此,本書建議大家編寫程式碼時仍以self作為例項方法的第一個引數名字,這樣便於他人閱讀程式碼。
物件的建立
在Python中,有兩種物件:類物件與例項物件。類物件只有一個,而例項物件可以有多個。
1 類物件
類物件是在執行class語句時建立的,如例所示。
在這裡插入圖片描述
在例中,Python執行class語句時建立一個類物件和一個變數(名稱就是類名稱),變數引用類物件。通過type()函式可以測試物件的型別。
在定義類時,還可以定義類屬性,如例所示。
在這裡插入圖片描述
在例中,第6行通過“類名.類屬性名”方式訪問類屬性。
2 例項物件
例項物件通過呼叫類物件來建立(就像呼叫函式一樣來呼叫類物件),每個例項物件繼承類物件的屬性,並獲得自己的名稱空間。例項方法的第一個引數預設為self,表示引用例項物件。在例項方法中對self的屬性賦值才會建立屬於例項物件的屬性,如例所示。
在這裡插入圖片描述
如果類中存在相同名稱的類屬性與例項屬性,則通過例項物件只能訪問例項屬性,如例所示。
在這裡插入圖片描述
此外,還可以通過賦值運算子修改或增加類物件與例項物件的屬性,如例所示。
在這裡插入圖片描述
** 構造方法**
Python中構造方法一般用來為例項屬性設定初值或進行其他必要的初始化操作,在建立例項物件時被自動呼叫和執行,如例所示。
在這裡插入圖片描述
上例中建立例項物件時,預設給school屬性賦值為’千鋒教育’。如果在建立例項物件時,由使用者指定school屬性的值,則可以在構造方法中新增額外引數,如例所示。
在這裡插入圖片描述
析構方法
析構方法一般用來釋放物件佔用的資源,在刪除物件和收回物件空間時被自動呼叫和執行,如例所示。
在這裡插入圖片描述
在例中,第5行定義一個析構方法,該方法名稱(del)是固定不變的,如果使用者沒有定義它,Python將提供一個預設的析構方法。第9行使用del語句刪除一個物件,此時會自動呼叫析構方法。當程式結束時,Python直譯器會自動檢測當前是否存在未釋放的物件,如果存在,則自動使用del語句釋放其佔用的記憶體,如本例中的s1物件。
類方法
類方法是類所擁有的方法,通過修飾器@classmethod在類中定義,其語法格式如下:
在這裡插入圖片描述
其中,cls表示類本身,通過它可以訪問類的相關屬性,但不可以訪問例項屬性,如例所示。
在這裡插入圖片描述
靜態方法
類方法可以通過類名或例項物件名呼叫,靜態方法也可以通過兩者呼叫,其語法格式如下:
在這裡插入圖片描述
其中,@staticmethod為裝飾器,引數列表中可以沒有引數。靜態方法可以訪問類屬性,但不可以訪問例項屬性,如例所示。
在這裡插入圖片描述

運算子過載

在Python中可通過運算子過載來實現物件之間的運算,如字串可以進行如下運算:
在這裡插入圖片描述
字串可以通過“+”運算子實現字串連線操作,其本質是通過__add__方法過載了運算子“+”,因此上述程式碼還可以寫成如下程式碼:
在這裡插入圖片描述
Python把運算子與類的例項方法關聯起來,每個運算子都對應一個方法。運算子過載就是讓類的例項物件可以參與內建型別的運算。
表中列出了部分運算子過載方法。
在這裡插入圖片描述
1 算術運算子過載
定義一個複數類並對其進行算術運算子過載,如例所示。
在這裡插入圖片描述
2 比較運算子過載
定義一個複數類並對其進行比較運算子過載,如例所示。
在這裡插入圖片描述
在例中,定義一個MyComplex類,通過__eq__ ()方法過載==運算子。
3 字串表示過載
當物件作為print()、str()函式的引數時,該物件會呼叫過載的__str__()方法,如例所示。
在這裡插入圖片描述
在例中,定義一個MyComplex類,通過__str__ ()方法過載字串表示。
4 索引或切片過載
當對例項物件執行索引、分片或for迭代時,該物件會呼叫過載的__getitem__()方法,如例所示。
在這裡插入圖片描述
在例中,定義一個Data類,通過__getitem__()方法過載索引與分片。
此外,在通過賦值語句給索引或分片賦值時,例項物件將呼叫__setitem__()方法實現對序列物件的修改,如例所示。
在這裡插入圖片描述
在例中,定義一個Data類,通過__ setitem__()方法過載索引或分片賦值。
5 檢查成員過載
當對例項物件執行檢查成員時,該物件會呼叫過載的__contains__()方法,如例所示。
在這裡插入圖片描述
在例中,定義一個Data類,通過__contains__()方法過載檢測成員運算子。

相關文章