詳解Objective-C學習筆記之面向對象編程
Objective-C學習筆記之面向對象編程是本文要介紹的內容,主要詳細的介紹了面向對象編程的內容,對于資深的C++程序員來說,面向對象編程不是什么新鮮的概念,類、對象、實例、方法這些概念就不再冗述了。和上一篇 Objective-C學習中對 C語言的擴展一樣,這篇主要側重于Objective-C中的OOP,有哪些與我們熟識的C++不同的概念。
- Point : NSObject
- {
- int X;
- int Y;
- }
- - (void) SetX: (int) X;
- - (void) SetY: (int) Y;
- - (void) Show;
- // Point
下面進行逐句分析。
“Point”告訴編譯器:“這是為名為Point的新類定義的接口。”,而后面的“NSObject”告訴編譯器,Point類是基于 NSObject類的。該語句表明每個Point類都是一個NSObject,并且每個Point都將繼承NSObject類定義的所有行為。
花括號中的內容是用于大量創(chuàng)建新Point對象的模板。它表明,創(chuàng)建新Point對象時,該對象由兩個元素構成——X和Y,每個創(chuàng)建出來的Point類對象都將擁有自己的X和Y。
隨后的代碼看起來像是C函數(shù)原型,在Objective-C中,它們稱為方法聲明。方法聲明指出每種方法的名稱、方法返回值的類型和某些參數(shù)。
前面的短線“-”表明這是Objective-C方法的聲明,這是一種區(qū)分函數(shù)原型與方法聲明的方式。
短線后面是方法的返回類型,位于圓括號中,void表示無返回值。Objective-C方法可以返回與C函數(shù)相同的類型:標準類型(整型、浮點型和字符型)、指針、對象引用和結構。
方法類型之后是方法名稱,如果方法使用參數(shù),在名稱的結尾處需要使用冒號。這個冒號是名稱的一部分,它告訴編譯器后面會出現(xiàn)參數(shù)。
參數(shù)的類型是在圓括號中指定的,緊隨其后的是參數(shù)名稱。
最后的“Point
- - (void) SetX: (int) thisX
- {
- X = thisX;
- } // SetX
- - (void) SetY: (int) thisY
- {
- X = thisY;
- } // SetY
- - (void) Show
- {
- NSLog(Point at (%d, %d)", X, Y);
- } // Show
- // Point
下面進行逐句分析。
@implementation是一個編譯器指令,表明它將為某個類提供代碼。類名(Point)出現(xiàn)在@implementation之后,該行的結尾處沒有分號。
接下來是各個方法的定義,它們不必按照在@interface指令中的順序出現(xiàn)。你甚至可以在@implementation中定義那些在@interface中無相應聲明的方法。可以把它們看成是私有方法,僅在類的實現(xiàn)中使用。
方法定義中的第一行看上去與@interface部分的聲明非常類似,二者間的主要差別就是結尾處沒有分號,另外還需要注意到我們將方法的參數(shù)重新命名了,@interface部分的方法聲明中使用了名稱X和Y,是為了確切告訴讀者參數(shù)的用處。在具體實現(xiàn)中,我們必須區(qū)分參數(shù)名稱和實例變量名稱,所以需要將參數(shù)重命名。
SetX方法和SetY方法的結構幾乎一樣,對于Show方法需要注意,方法名的結尾處沒有冒號,說明它不使用任何參數(shù)。
最后的“@end”代碼告訴編譯器,我們已經(jīng)完成了Point類的實現(xiàn)。
實例化對象
實例化對象就是根據(jù)我們前面寫好的聲明創(chuàng)建一個新對象。為了創(chuàng)建新的對象,我們先來熟悉一個新的操作符——“[]”操作符。
在C語言中,程序員使用方括號引用數(shù)組元素。而在Objective-C中,方括號還有其他意義:它們用于向某個對象發(fā)送消息,通知其執(zhí)行某種操作。在在方括號內,第一項是對象,其余部分是你需要發(fā)送的消息。例句如下:
- [Point new]
Objective-C具有一個極好的特性,你可以把類當成對象來向類發(fā)送消息。在本例中,我們就是向Point類發(fā)送new消息,通知Point類創(chuàng)建一個新對象。以下是完整的實例化對象代碼。
- int main (int argc, const char* argv[]){ id thisPoint;
- thisPoint = [Point new];
- [thisPoint SetX: 0];
- [thisPoint SetY: 0];
- [thisPoint Show];
- }
- // main
下面進行逐句分析。
這個main()函數(shù)和普通C程序中的main()函數(shù)沒有什么區(qū)別,參數(shù)argc保存啟動參數(shù)的數(shù)量,因為程序名常用作啟動參數(shù)傳遞,所以argc通常為1或更大。參數(shù)argv數(shù)組用于保存啟動參數(shù),argv[0]通常就是程序名,如果有其他啟動參數(shù),依次存放在argv[1]、argv[2]等等。
id代表identifier,是一種泛型,用于表示任何種類的對象。實際上,id就是指向某個對象的指針。
通過給Point類發(fā)送new消息,創(chuàng)建了一個Point類的實例,thisPoint中保存的就是指向這個市里的指針。
接下來就是通過給thisPoint對象發(fā)送SetX和SetY消息來設定其元素X和Y。需要注意到,和方法聲明中類似,[]操作符發(fā)送給對象的消息需要攜帶參數(shù)時,在消息之后需要使用冒號,而攜帶的參數(shù)就跟隨在冒號的后面。
最后就是通過給thisPoint對象發(fā)送Show消息顯示其相關信息。同樣需要注意,當發(fā)送的消息沒有參數(shù)時,后面千萬不可使用冒號。
繼承
編寫面向對象的程序時,你所創(chuàng)建的類和對象之間存在一定的關系。它們協(xié)同工作才能實現(xiàn)程序相應的功能。處理類和對象間的關系時,OOP有個很重要的特性叫做繼承,使用繼承可以定義一個具有原有類所有功能的新類。
在前文的@interface部分聲明新類的時候,其實已經(jīng)用到了繼承的語法。
- @interface Point : NSObject
如上例中所示,冒號后的標識符就是需要繼承的類。在Objective-C中,可以從非類中繼承對象,但如果使用Cocoa,會希望從NSObject繼承對象,因為NSObject提供了大量有用的特性。@interface部分最簡單的繼承代碼可以如下所示:
- @interface MyPoint : Point@end // MyPoint
這時,MyPoint類就繼承了Point類的所有數(shù)據(jù)成員和方法。在下面的文字中,我們統(tǒng)一用超類來描述所繼承的類,用子類來描述實施繼承的類。這里Point就是MyPoint的超類,而MyPoint就是Point的子類。
我們在寫新的子類時,有時為了在類中引入某個獨特的特性,需要添加新方法。還有些時候,可能需要替換或增強由這個新類的某個超類所定義的現(xiàn)有方法。
Objective-C提供某種方法來重新方法,并且仍然調用超類的實現(xiàn)方式。為了調用繼承方法的實現(xiàn),需要使用super作為方法調用的目標。
繼續(xù)沿用前面給出的例子,假設我們發(fā)現(xiàn)之前采用的坐標有偏差,實際上的X坐標應為原有的X-10。我們便可在子類MyPoint中對Point類的Show()方法進行如下重寫。
- @implementation MyPoint
- - (void) Show{ XX = X - 10; [super Show];
- }
- // Show @end // MyPoint
從上面的代碼中,我們通過向super發(fā)送Show消息使用了超類的相應代碼。
這里的super既不是參數(shù)也不是實例變量,向super發(fā)送消息時,實際上是在請求Objective-C向該類的超類發(fā)送消息。如果超類中沒有定義該消息,Objective-C將按照慣常的方式在繼承鏈中繼續(xù)查找對應的消息。
小結:詳解Objective-C學習筆記之面向對象編程的內容介紹完了,希望本文對你有所幫助。