初學者開發(fā)文檔:Objective-C語言學習基礎
Objective-C語言學習基礎是本文要介紹的內容,在面向對象編程中必須具有的最基本的功能是向對象發(fā)送消息。在Objective-C中,我們采用以下的結構發(fā)送消息:
- [receiver message];
receiver是你要向它發(fā)送消息的對象,message是你要接收對象執(zhí)行的method。例如,假設在我們的程序中有一個對象dataTable,我們想要更新它的數(shù)據(jù)。要這樣做,我們要在程序中包含以下的語句,給數(shù)據(jù)表發(fā)送消息:
- [dataTable reloadData];
在Objective-C的method中,參數(shù)用冒號進行標記。
- [textField setEditable:YES];
你可以有多個參數(shù),每個以冒號為引導。消息也可以進行嵌套,如果參數(shù)類型和返回類型是一致的話。例如,我們可以讀取滾動條的值并把它在文本區(qū)內顯示出來。
- [textField setDoubleValue:[slider doubleValue]];
這里,[slider doubleValue]是[textField setDoubleValue: ]的參數(shù)。doubleValue命令返回值為double類型,與setDoubleValue的輸入?yún)?shù)類型一致。
關于數(shù)據(jù)類型,在Objective-C中,對象的類型全部為id。id類型的變量僅僅只是對象的描述符而已。事實上,它們是指向對象數(shù)據(jù)結構的指針,這個超出了我們討論的范圍。在代碼中,我們象使用其它變量一樣,產(chǎn)生指向對象的變量。
- id anObject;
在Objective-C中,缺省的返回數(shù)據(jù)類型為id。所以,如果你的method沒有指定返回類型,它會自動分配為id。
也可以把一個數(shù)據(jù)變量的類型指定為特定的類。這稱作靜態(tài)類型。所有指向對象的變量實際上都是指向它們內存位置的指針。這種實現(xiàn)方式在多數(shù)情況下,對編程人員是透明的。當然,如果是靜態(tài)類型的話,就不是透明的了。
當我們創(chuàng)建一個id類型的變量,事實上它隱含為一個對象的指針。id定義為指針類型——一個對象的標識。但如果你有一個指向字符串的變量,而且你象把它靜態(tài)聲明為NSString,你必須在代碼中顯式地聲明這個變量是一個指針。這可以通過C的指針聲明來實現(xiàn):
- NSString *aString;
變量名前面的星號不是變量名的一部分,而是表明aString是NSString這個對象的指針。這是你唯一需要知道的關于對象變量的指針屬性的知識。只有在聲明新的變量的時候才需要使用C的指針結構。在你隨后引用aString的時候,它就好象其它變量一樣。
如果你對指針或C語言本身不熟悉,可以參考Brian Kerrnighan和Dennis Ritchie(C語言的作者)編寫的《C編程語言》。另外,我還想推薦Steve Oulline編寫的《使用C編程》。
其它產(chǎn)生嵌套method的方法
現(xiàn)在我們有一個對象的數(shù)據(jù)類型,我們可以用與上面不同的方式產(chǎn)生嵌套的method。一個返回id類型的消息可以作為其它消息的接收者。
- double number;
- number=[anArray lastObject] doubleValue];
當然,我們假定[anArray lastObject]返回的對象能夠相應doubleValue這個消息。我們擁有了一個對象的陣列。[anArray lastObject]返回的對象處于陣列的最頂端,然后它接收到一個doubleValue的消息。
在Objective-C中定義新的類
現(xiàn)在,我想和你討論在Objective-C源代碼中如何定義一個新的類。按照界面和實現(xiàn)分開的精神,Objective-C在兩個分開的文件中定義新的類——一個界面文件和一個實現(xiàn)文件。
界面文件包括使用類所需要的全部信息,包括所有實例變量的聲明和method的定義。程序員通過研究界面文件了解哪一個類適合使用。實現(xiàn)文件包括method如何實現(xiàn)的源代碼。
一個類的界面和實現(xiàn)往往分在兩個文件中,雖然對編譯器來說并沒有這樣的強制要求。實現(xiàn)文件的后綴為:.m,也就是Objective-C源文件的擴展名。界面文件的擴展名為.h,和C語言的頭文件是一樣的。類文件的名字通常與類的名字一樣,雖然這也不是編譯器的強制要求。這樣,一個叫“Circle”的類會在文件Circle.h和Circle.m中定義。
界面文件
界面文件聲明構成類的實例變量和method。一個界面文件的結構為:
- @interface 類的名字 : 它的超類的名字
- {
- 實例變量的聲明
- }
- method的聲明
- @end
界面聲明總以編譯器指令@interface開始,@end結束。在***行跟在@interface之后的是類的名字。在類的名字后面是一個冒號,這之后是你的類所繼承的類的名字——它的超類。如果你沒有指定超類,那么它就會假定你是在創(chuàng)建一個新的根類,就好象Cocoa中的NSObject一樣。
***行以后在大括號內的是實例變量的聲明。這是method所要操作的類的數(shù)據(jù)結構。在我們假設的Circle類中,實例變量的聲明也許會是這樣的:
- double radius;
- double xLacation;
- double yLocation;
- NSColor *color;
實例變量的變量聲明總是以數(shù)據(jù)類型在前面。后面我們會學到,NSColor是操作顏色的應用庫的類。
在實例變量聲明之后是method的聲明。象標準的C函數(shù),Objective-C中的method有返回值和輸入?yún)?shù)。另外,method既可以是類的也可以是實例的。類method只能由前面討論過的類對象來調用,而實例method則可以由類的任何對象來調用。method名前面的加號表示這是一個類method。
- + alloc
以減號開頭的method聲明表示這是一個實例method。
- - (void) setXLocation: (double)x YLocation: (double)y;
method的返回值由method名前面括號內的類型確定。參數(shù)跟在冒號之后,多個參數(shù)由參數(shù)名和空格分開。象method的返回類型一樣,參數(shù)的數(shù)據(jù)類型也是由參數(shù)名前面括號內的類型決定。
如果一個類與它的超類由關聯(lián),應該導入它的超類的界面文件,通常是超類的名字后面加上.h構成。
- #import "ItsSuperclass.h"
#import語句的作用和你也許已經(jīng)很熟悉的#include很相似——區(qū)別只是#import更智能化一些。#import***的優(yōu)勢在于它自動檢查一個文件是否已經(jīng)被導入過,而不會重復進行導入。#include并不進行這個檢查。
實現(xiàn)文件
實現(xiàn)文件是你的類的代碼核心部分。這個文件包括你使得你的method運作的所有代碼——使得你的類能夠完成一些有意義的工作。界面文件使你的類的描述性部分,使其它程序員編寫的代碼可以與你的類一起工作。實現(xiàn)文件使你的類完成需要的工作。
實現(xiàn)文件的格式與界面文件的有些類似:
- #import "類名.h"
- @implementation 類名 : 超類名
- {
- 實例變量聲明
- }
- method定義
- @end
每個類的實現(xiàn)都必須引用它的界面文件。因為界面文件中已經(jīng)聲明了你所繼承的超類,因此這部分可以省略。這更加明確了實現(xiàn)文件主要關于method實現(xiàn)的概念。這樣,在實踐中,實現(xiàn)文件只需要以下的代碼:
- #import "類名.h"
- @implementation 類名
- method定義
- @end
method的定義和C函數(shù)的定義類似。名字應該與界面文件完全一致(沒有分號),method的實現(xiàn)代碼包括在名字后面的一對大括號中。例如,我們的Circle類的method為:
- + alloc
- {
- 你的代碼
- }
- - (void)setXLocation: (double)x YLocation: (double)y
- {
- 你的代碼
- }
你也許會奇怪為什么+ alloc沒有返回值。Objective-C的缺省返回值是id——也就是說,它缺省返回一個對象。+ alloc這個method設計為返回類的一個對象,因此沒有必要指明返回值。在提到+ alloc這個method時,我要指出你很少需要自己實現(xiàn)這個method。NSObject這個類會處理這個問題。+ alloc的目的是為新創(chuàng)建的對象分配內存。下面的內容會涉及創(chuàng)建新對象的細節(jié)。
實例變量可以在你的method中直接引用。不需要特別指明,所有實例變量與method處于同一個名域。它們就象C中全局變量。這樣,我們可以象下面那樣定義第二個method:
- - (void)setXLocation: (double)x YLocation: (double)y
- {
- xxLocation = x;
- yyLocation = y;
- }
另外,也可以定義局部變量,它們具有更加局限的作用區(qū)域。例如,在上面的第二個method中,我們可以添加一個沒用的中間變量:
- - (void)setXLocation: (double)x YLocation: (double)y
- {
- double tempX;
- double tempY;
- tempX = x;
- tempY = y;
- xLocation = tempX;
- yLocation = tempY;
- }
你會發(fā)現(xiàn)任何可以應用于標準C函數(shù)的,都可以應用于類的method。
創(chuàng)建新對象
要創(chuàng)建一個新對象,你可以向你想創(chuàng)建的實例所屬的類的類對象發(fā)送一個alloc消息。例如,我想創(chuàng)建Circle類的一個實例,我們可以這樣做:
- id aCircle;
- aCircle = [Circle alloc];
記住,alloc返回一個對象,所以你打算存儲你所創(chuàng)建的實例的變量應該是id類型的。一旦創(chuàng)建了新的實例,我們需要初始化它的實例變量。這可以想新創(chuàng)建的對象發(fā)送一個init消息。
- [aCircle init];
初始化必須在分配內存之后立刻進行,所以一般用兩個嵌套的消息來完成。
- aCircle=[[Circle alloc] init];
缺省地,init把所有實例變量初始化為0。你可以創(chuàng)建你自己的初始化method,也稱為構造函數(shù),來安裝你的需求初始化變量。通常構造函數(shù)以“init”開頭。因為構造函數(shù)需要和一個對象的實例變量打交道,所以它應該是一個實例method,而不是象“alloc”那樣的類method。例如,你可以為我們的Circle類創(chuàng)建一個構造函數(shù),把半徑初始化為10。這個method應該是這樣的:
- - (void)initWithRadius: (double)r;
- {
- rradius = r;
- }
任何沒有在你的構造函數(shù)中初始化的實例變量缺省地設置為0。
在Project Builder中
到現(xiàn)在位置,我還沒有提到Project Builder。但我現(xiàn)在想談到一個與現(xiàn)在討論有關的特性。Project Builder包含類的界面和實現(xiàn)文件的模板。你獲得是一個繼承自基礎庫中NSObject類的框架——你所需要做的是用你自己的數(shù)據(jù)結構和method來填充它。所以,現(xiàn)在你應該了解類在源代碼級的結構,同時也知道怎么簡單地創(chuàng)建它。
現(xiàn)在我們已經(jīng)基本介紹完入門的知識,下面將要進入真實程序的編程。下一次,我將會介紹Interface Builder。我們對Interface Builder的學習主要是通過實驗。
小結:初學者開發(fā)文檔:Objective-C語言學習基礎的內容介紹完了,希望本文對你有所幫助!