關於類的定義:
編譯器雖然不強制,但是類型的介面申明與實現代碼最好放在兩個不同的檔案中,以方便使用這些類的開發人員查看。
實現的檔案使用 .m 結尾。
介面檔案可以使用任何其它的副檔名。因為它經常被 included 到其它的檔案中,因此通常使用 .h 的副檔名。
分離介面與實現是物件導向設計方法中推薦的做法。
@interface ClassName : ItsSuperclass
{
instance variable declarations
}
method declarations
@end
介面定義開始於 @interface ,結束於 @end
靜態方法使用 + 開頭,執行個體方法使用 - 號開頭,如:
+ alloc;
- (void)display;
執行個體變數可能與一個執行個體方法同名。
傳回值使用標準C文法進行類型轉換。
如果方法傳回值或參數未指定類型,那麼則使用預設的類型即 id
方法如果接受不定數量的參數,可以使用逗號和省略符號:
- makeGroup:group, …;
在使用到相互關聯類型的時候都要使用
#import "SomeClass.h" 來引用一個類型
類型介面定義時需要 import 它的父類介面
這種鏈式引用,保證了一個 class 在調用時它的所有父類都已經被引用。
有一點需要注意:如是先行編譯的包,那麼引用的時候需要引用這個先行編譯的內容而不是原始的 .h 檔案。
如果 interface 中還使用到了其它類型的成員變數並且 include 檔案裡面沒有提到的,應該使用 :
@class Retangle, Circle; 方式來引入
它告訴編譯器這些 Sybol 是類型名稱,不要 import 他們的標頭檔(僅限於沒有使用成員方法的時候),如:
- (void)setPrimaryColor:(NSColor *)aColor;
這樣做的目的是讓編譯器和連接器的可見代碼最小並防止循環參考問題。
總之,只在必要的時候才 import interface, 否則只需要 @class 即可。
如果不是公開方法,則不需要在 interface 中申明。
關於類的實現:
類的實現塊寫法與介面定義的寫法類似:
@implementation ClassName : ItsSuperclass
{
instance variable declarations
}
method definitions
@end
每個實現檔案應該 import 它自己的介面定義檔案。有些可以安全地省略:父級 class 名稱,執行個體變數申明。
在執行個體方法中使用執行個體變數並不需要加首碼,編譯器可以自動識別。
In referring to the instance variable of a statically typed object, the structure pointer operator (->) is used.
如果要訪問一個類型化變數的成員變數則需要使用 "->"
- makeIdenticalTwin
{
if ( !twin ) {
twin = [[Sibling alloc] init];
twin->gender = gender;
twin->appearance = appearance;
}
return twin;
}
範圍:
@private @protected @public @package
未申請的範圍 預設為 protected
在執行個體方法中調用其它的執行個體方法或父級的執行個體方法:
- reposition
{
...
[self setOrigin:someX :someY];
...
}
or:
- reposition
{
...
[super setOrigin:someX :someY];
...
}
self 可以被賦值,但是不要這樣做, super 只能被用作訊息接受方。
下面的代碼,在執行個體方法中需要申請一個與自己相同類型的執行個體變數:
self = [[Rectangle alloc] init]; // BAD
id newInstance = [[Rectangle alloc] init]; // GOOD
id newInstance = [[self alloc] init]; // EXCELLENT
最後那個最好,因為它始終指向當前的 class (這樣不用擔心在子類中寫死指向到父類的情況)