當然舉這個例子是比較極端啦,這樣的情況應該很少發生。如果你跑一下以上的的程式碼,會得到錯誤訊息”expected specifier-qualifier-list before ‘B’”,意思就是說這個B類別並不存在。A跟B兩個類別互相有需要,但B還沒出生,變成是雞生蛋蛋生雞的問題,這時候就可以用上@class這個語法了。只要在@interface A前面加一行:
1
@classB;
這行就是告訴編譯器說「這個B是一個類別,至於這個B類別的內容你不用管,反正遲早會告訴你,你先用就是了」,這樣一來就可以順利通過編譯了。不過寫了@class不代表就可以不用實作那個類別的內容,如果到時候沒有import B的header進來或是沒有實作B類別,硬是要用的話在編譯過程就會跳出一個訊息”warning: receiver ‘B’ is a forward class and corresponding @interface may not exist”。
// interface@interfaceBook : NSObject{intprice;}@propertyintprice;+(void)printBookInfo;@end// implementation@implementationBook@synthesizeprice;// 自定setter-(void)setPrice:(int)p{// 故意讓傳入值變2倍price=p*2;}+(void)printBookInfo{NSLog(@"Hello, This is a book");}@end
Book*b=[[Bookalloc]init];// 一般的setter用法[bsetPrice:300];// 一般的getter用法NSLog(@"the price of the book is %d",[bprice]);// Objective-C 2.0之後可使用點語法,它會自動呼叫setter並將值傳給它b.price=200;// 這裡則是呼叫getter把值傳回來NSLog(@"the price of the book is %d",b.price);[brelease];
在別的程式語言裡,會用關鍵字class來定義類別,在Objective-C的話則是用@interface這個關鍵字來定義。不要搞混這個@interface跟其它程式語言的interface,它們講的是不同的東西(其它程式語言的interface在Objective-C裡比較像是Protocol,之後會再做說明)。為了讓環境單純一點,我們直接開一個Command Line Tool的專案來練習手感:
#import <Foundation/Foundation.h>#import "Book.h"intmain(intargc,constchar*argv[]){NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];// 新增一個Book實體Book*b=[[Bookalloc]init];// 設定價錢[bsetPrice:20];// 把價錢印出來NSLog(@"the price of the book is %i",[bprice]);// 用完記得放掉[brelease];// 這是類別方法[BookprintBookInfo];[pooldrain];return0;}