第十四章 對象
在Python中,對象(object)是什么?我們先看前兩個概念:
(1)列表——收集變量(也就是數(shù)據(jù))
(2)函數(shù)——收集功能(也就是代碼)
而我們今天學的對象,則將是將這種收集思想再進一步——收集列表和函數(shù)本身。
等等,收集了又怎樣?我們可以不用了解那么深入,只需要知道Python是面向?qū)ο螅╫bject oriented)的編程語言,有很多對象可以幫我們實現(xiàn)很多功能,我們不用自己寫出來,只要寫個代碼調(diào)用它就好了。
14.1 真實世界中的對象
在真實世界中,對象相當于一個東西,它有自己的屬性(attribute)或特性(property),如大小、顏色等;也有動作,如撿球、拋球等。
14.2 Python中的對象
在Python中,一個對象的特征就是屬性;動作則稱為方法(method)。
如果在Python中定義一個“球”,我們可以給他建立如下定義:
什么是屬性?
屬性就是一些信息(數(shù)字、字符串等),其實也是變量的一種,只不過它包含在對象中。屬性可以:
(1)顯示:print ball.size
(2)賦值給自己:ball.color = 'green'
(3)賦值給其他變量:myColor = ball.color
(4)賦值給其他對象的屬性:myBall.color = yourBall.color
什么是方法?
方法其實就是包含在對象中的函數(shù)。
14.3 對象=屬性+方法
利用對象,可以將一個東西的屬性和方法(也就是你知道的事情和希望可以做的事情)收集到一起。屬性是信息,方法是動作。
14.4 這個點是什么
前面我們看到:
(1)object.attribute
(2)object.method()
這兩種用法。中間的點,是Python使用對象屬性和方法的一種記法,稱為“點記法”。
14.5 創(chuàng)建對象
Python創(chuàng)建對象一共有兩步:
(1)第一步是創(chuàng)建對象類(class),用來放入對象的描述或藍圖。
(2)第二部是創(chuàng)建對象的實例(instance)。
具體請看下面的例子:
初始化對象:__int__()方法
有時候,除了創(chuàng)建類和實例本身,我們還需要第三步——初始化(initializing)。
初始化可以使用一個特定的方法實現(xiàn):
假如現(xiàn)在print myBall,得到的會是這樣的結(jié)果:
要改變這個信息,需要用到一個__str__()方法,它是一個“類方法”:
改變類型:__str__()方法
就像init方法一樣,str方法是Python創(chuàng)建類時自動包含的“魔法方法”,也叫特殊方法(special method)。
__str__()方法在這里的含義是,告訴Python打印一個對象時,具體要顯示什么內(nèi)容,默認會顯示下面的內(nèi)容:
(1)實例在哪里定義(默認為__main__)
(2)類名(Ball)
(3)存儲實例的具體空間(這里是0x109577dd0)
下面的例子使用了__str__()改變了打印的對象:
什么是self
我們前面多次用到了“self”,如下面這個例子:
def bounce(self):
這個self是什么意思呢?我們先看Ball類創(chuàng)造的兩個實例:
catersBall = Ball("red", "small", "down")
warrensBall = Ball("green", "medium", "up")
這樣,我們調(diào)用其中一個實例時(以warrens為例),可以直接用warrensBall.bounce來實現(xiàn):
(1)首先,bounce是一個方法;
(2)方法必須知道是哪個實例調(diào)用了它:是caters,還是warrens或其他?
(3)因此,前面的def bounce(self)方法中的self參數(shù),就會告訴bounce方法,是warrens調(diào)用了這個方法。以上成為實例引用(instance reference)。
附:我花了好長時間也沒弄明白這個self方法,另外這一章也感覺比之前難懂很多,那么就先放放,等上手了例題再回來補充吧~
14.6 一個示例類——HotDog
之前我們做過了熱狗的排列組合練習,現(xiàn)在我們來給熱狗們設置一些屬性和方法,讓這個程序更加智能些。
首先給熱狗設置一些屬性:
(1)cooked_level:代表熱狗的生熟程度,0~3為生,5表示烤好,8以上已經(jīng)烤焦了!
(2)cooked_string:描述熱狗生熟程度的字符串。
(3)condiments:熱狗上的配料列表,如番茄醬、芥末醬等。
然后是熱狗的一些方法:
(1)cook():烤熱狗。
(2)add_condiment():給熱狗加上配料。
(3)__init__():創(chuàng)建實例并設置默認屬性。
(4)__str__():讓print的結(jié)果好看點。
下面是步驟:
(1)首先需要定義熱狗這個類:使用__init__方法
(2)建立一個烤熱狗的方法:cook(),其中的time是用來增加烤制級別的。
(3)創(chuàng)建熱狗的一個實例,并檢查它的屬性。
(4)把以上內(nèi)容都放到一個程序中,并運行:
(5)現(xiàn)在來測試cook方法:
(6)增加其他的功能:顯示、加配料等
14.7 隱藏數(shù)據(jù)
如果限制對對象的數(shù)據(jù)訪問,使得它只能通過方法來獲取數(shù)據(jù)、修改數(shù)據(jù),這就叫做數(shù)據(jù)隱藏(data hiding)。
14.8 多態(tài)和繼承
接下來我們學習對象最重要的兩個方面:多態(tài)(polymorphism)和繼承(inheritance)。這兩個詞有點深奧,但正因為有這兩方面,才讓對象如此有用。
(1)多態(tài)——同一個方法,不同的行為
多態(tài)簡單來說就是:同名的方法,在不同的類中,可以實現(xiàn)不同的行為。
例如,假設我們要建立一個程序做幾何題,分別計算不同形狀(如正方形和三角形)的面積,這時候我們可以建立兩個類,然后按下面的來操作:
以上兩個形狀,都用了getArea的方法,但每個形狀的方法做的工作不同,這就是多態(tài)的一個例子。
(2)繼承——向父母學習
在真實的(非編程的)世界中,人們可以從他們的父母或其他家人處繼承一些東西,如財物、身體特征等。而在面向?qū)ο缶幊讨校惪梢詮钠渌惸抢锢^承屬性和方法,這樣的類稱為一個“家族”,“家族”中的每個類共享相同的屬性和方法。這樣一來,給“家族”新增成員的時候,新的類就不用從頭開始寫起。
從其他類繼承屬性或方法的類,我們成為派生類(derived class)或子類(subclass)。我們看一下下面的例子:
假如我們要建立一個游戲,玩家一路上可以撿起不同的東西,如食物、錢或衣服。我們建立一個類,叫GameObject。它有一些屬性如name、coin、apple和hat等;它還有些方法,如pickUp()等。所有的游戲?qū)ο蠖加泄餐姆椒ê蛯傩浴?/p>
另外我們還有Coin這個子類,從GameObject派生。它需要繼承GameObject的name屬性和pickUp等方法,并需要一個value屬性和一個spend()方法。
下面是這些類的代碼:
14.9 未雨綢繆
上面的代碼看似沒有什么實質(zhì)內(nèi)容,但它有助于我們提前思考、組織想法,并給其他人解釋我們要做什么。這種“未雨綢繆”的方法,我們也可以“空函數(shù)”或代碼樁(code stub)實現(xiàn)。
要建立代碼樁,可以使用pass關鍵字作為占位符,如:
你學到了什么
(1)什么是對象、屬性和方法
(2)什么是類,以及如何創(chuàng)建類的實例
(3)特殊方法:__init__()和__str__()
(4)多態(tài)、繼承和代碼樁
練習題
記在前面,先區(qū)分一下類、對象和實例,感覺現(xiàn)在還沒弄明白。書上說的是,“類”只是對象的定義或藍圖,從這個藍圖建立對象時得到的就是實例。這里放一個討論的連接,下面是另一種比喻,日后繼續(xù)加深印象~
(1)為BankAccount建立一個類定義。它的屬性包括賬戶名(字符串)、賬號(字符串或整數(shù))和余額(浮點數(shù)),另外還需要有一些方法用來顯示余額、存錢和取錢。
(2)建立一個可以掙利息的類,叫InterestAccount。它繼承BankAccount的屬性和方法,并且有一個對應的利息率的屬性,另外還要有一個方法計算及更新余額(年利息)。
先回顧一下子類的建立方法:
class 子類名(父類名):
小結(jié)
這一章學的挺不痛快,原因一是沒之前那么簡單,涉及到類、對象和實例的關系比較抽象,不能一下子明白;第二是不太自信,碰到比較難、比較陌生的題,會畏懼、會害怕。
這一章也是目前我參考網(wǎng)上其他學習筆記最多的一章,總的來說付出跟收獲是成比例的,繼續(xù)加油吧~