Objective-C——實現物件導向程式設計
過程式程式建立在函式之上,資料為函式服務。物件導向程式設計從相反的角度來看待問題,它以程式的資料為中心,函式為資料服務。在OOP中,不再重點關注程式中的函式,而是專注於資料。
這聽起來非常有趣,但它如何工作呢?在OOP中,資料通過間接方式包含對自身操作的引用程式碼。不是通知drawRectangle()函式“使用這個形狀結構繪製矩形”,而是要求矩形“繪製自身”(天哪,聽起來太荒謬了,但事實上卻並不荒謬)。通過間接方式的威力,矩形資料知道如何查詢相應的函式繪製圖形。
那麼,物件到底是什麼呢?它其實是一種神奇的C struct。通常,該結構能通過函式指標查詢與之相關的程式碼。圖3-1展示了4種Shape物件:兩個正方形、一個圓形和一個橢圓形。每個物件都能查詢相應的函式並實現其繪圖功能。
每個物件都有自己的draw()函式,知道如何繪製特定的形狀。例如,Circle物件的draw()函式知道如何繪製圓形,Rectangle的draw()函式知道繪製由4條直線構成的矩形。
Shapes-Object程式(程式碼請參考03.10-Shapes-Object)可以完成與Shapes-Procedural相同的功能,但前者使用Objective-C的物件導向特性來實現。以下是Shapes-Object的drawShapes()程式碼:
該函式包含一個迴圈,用於輸出陣列的每種形狀。在迴圈過程中,程式通知形狀物件繪製自身。 注意區分該形式的drawShapes()與原始版本有何不同。首先,本函式更簡短!程式碼不必詢問每個形狀的種類。
另一個不同點是函式的第一個引數shapes[],此刻它是一個id陣列物件。什麼是id?它是與大腦有關的心理學術語,用於描述天生的本能衝動和原始過程嗎?在本例中並非表示此意,它代表identifier(識別符號)。id是一種泛型,用於表示任何種類的物件。回憶一下,物件是帶有程式碼的C struct。因此,id實際上是一個指標,指向其中的某個結構。在本例中,結構由各種形狀構成。
drawShapes()函式的第三個變化是迴圈主體:
第一行看上去像普通的C語言。程式碼從shapes陣列獲取id(即指向某個物件的指標),並將其賦值給名為shape(它具有型別id)的變數。這只是一種指標賦值過程,它實質上並不會複製shape的全部內容。看看圖3-2,注意Shapes-Object中各種可用的形狀。shapes[0]是一個指向紅色圓形的指標,shapes1是一個指向綠色矩形的指標,shapes2是個指向藍色橢圓形的指標。
現在,我們看看函式的最後一行程式碼:
非常奇怪吧。這是怎麼回事呢?我們知道,C使用方括號引用陣列元素,但在此我們並沒有使用陣列實現任何功能。在Objective-C中,方括號還有其他意義:它們用於通知某個物件該做什麼。在方括號內,第一項是物件,其餘部分是你需要物件執行的操作。在本例中,我們通知名稱為shape的物件執行draw操作。如果shape是圓形,我們會得到圓形;如果shape是矩形,我們會得到矩形。
在Objective-C中,通知物件執行某種操作稱為傳送訊息(有些人也將其稱為“呼叫方法”)。程式碼[shape draw]表示向shape物件傳送draw訊息。[shape draw]可以理解成“向shape傳送draw”。至於形狀如何實際繪製圖形,則取決於shape的實現。
向物件傳送訊息時,如何呼叫必要的程式碼呢?這是通過幕後名為類的幫手來協助完成的。
請看圖3-3。該圖的左側展示了shapes陣列中索引為0的circle物件,該物件最近在圖3-2中出現過。circle物件含有一個指向其類的指標。類是一種結構,用於描述該種類物件的構造。在圖3-3中,Circle類含有一個指標指向用於繪製圓形、計算圓形的面積以及實現其他必要功能的程式碼。
類物件有什麼用呢?就讓每個物件直接指向它的程式碼不是更簡單嗎?確實是更簡單一些,而且某些OOP系統也是那樣做的。但是,擁有類物件會具備極大的優勢:如果在執行時改變某個類,則該類的所有物件會自動繼承這些變化(我們將在後面各章中進一步討論該內容)。
圖3-4展示了draw訊息經過怎樣的過程最終呼叫了circle物件中適當的函式。
以下是圖3-4中展示的步驟。
(1) 物件是訊息(圖中的圓形)的目標,需要查詢它,看看它屬於什麼類。
(2) Circle類瀏覽其程式碼,查詢draw函式的位置。
(3) 找到draw函式後,將執行繪製圓形的函式。
圖3-5展示了基於陣列中的第二個形狀(它是一個綠色的矩形)呼叫[shape draw]時的情況。
圖3-5中使用的步驟和圖3-4中的步驟幾乎相同。
(1) 查詢訊息(圖中的矩形)的目標物件,看看它屬於什麼類。
(2) Rectangle類查詢其程式碼塊,然後獲取draw函式的地址。
(3) Objective-C執行可繪製矩形的程式碼。
該程式展示了一些非常棒的間接操作!在該程式的過程式版本中,我們必須編寫程式碼來決定要呼叫哪個函式。現在,可以由Objective-C在幕後作出決定,它將查詢物件屬於哪個類。這可以降低呼叫錯誤函式的機率,同時使程式程式碼更易於維護。
相關文章
- Go物件導向程式設計OOP的實現Go物件程式設計OOP
- 物件導向程式設計物件程式設計
- Python 物件導向程式設計Python物件程式設計
- 十三、物件導向程式設計物件程式設計
- Python物件導向程式設計Python物件程式設計
- 程式設計思想 物件導向程式設計物件
- js物件導向程式設計JS物件程式設計
- 十六、物件導向程式設計物件程式設計
- JS物件導向程式設計(一):物件JS物件程式設計
- 06 物件導向程式設計 (續)物件程式設計
- Python - 物件導向程式設計 - @propertyPython物件程式設計
- Python物件導向程式設計(1)Python物件程式設計
- Scala的物件導向程式設計物件程式設計
- Python - 物件導向程式設計 - super()Python物件程式設計
- JavaScript物件導向程式設計理解!JavaScript物件程式設計
- 物件導向程式設計C++物件程式設計C++
- Python OOP 物件導向程式設計PythonOOP物件程式設計
- python技能--物件導向程式設計Python物件程式設計
- javascript:物件導向的程式設計JavaScript物件程式設計
- JS物件導向的程式設計JS物件程式設計
- Javascript 物件導向程式設計(一)JavaScript物件程式設計
- Javascript 物件導向程式設計(二)JavaScript物件程式設計
- Javascript 物件導向程式設計(三)JavaScript物件程式設計
- 一個在 Objective-C 和 Swift 中實現剖面導向程式設計的故事ObjectSwift程式設計
- 真的可以,用C語言實現物件導向程式設計OOPC語言物件程式設計OOP
- C++物件導向程式設計——遞迴實現字串的反序C++物件程式設計遞迴字串
- JavaScript-設計模式-物件導向程式設計JavaScript設計模式物件程式設計
- JavaScript設計模式之物件導向程式設計JavaScript設計模式物件程式設計
- 14 Python物件導向程式設計:反射Python物件程式設計反射
- python物件導向程式設計基礎Python物件程式設計
- 物件導向程式設計,不美了麼?物件程式設計
- 圖解python | 物件導向程式設計圖解Python物件程式設計
- python之物件導向程式設計(一)Python物件程式設計
- 史上最全 Python 物件導向程式設計Python物件程式設計
- 淺談PHP物件導向程式設計PHP物件程式設計
- JS物件導向程式設計(三):原型JS物件程式設計原型
- [筆記]物件導向的程式設計筆記物件程式設計
- python基礎(物件導向程式設計)Python物件程式設計
- 前端_JavaScript_物件導向程式設計前端JavaScript物件程式設計