看個例子:
Wolf.h
#import <Foundation/Foundation.h> @interface Wolf : NSObject { NSString *_name; int _age; } -(void)SetName:(NSString *)name; -(NSString *)name; -(void)SetAge:(int)age; -(int)age; +(void)bray; @end
在@interface與@end中間宣告這個類別有哪些{變數}與方法,而Wolf是這個類別的名稱,後面的冒號表示繼承於誰,NSObject是所有類別的最源頭,方法前面的符號 - 表示物件方法, + 表示類別方法。
類別命名規則,第一個字通常是大寫,常看到的NS表示NextStep,你也可以取自己的前綴字,如BH, WTF....。變數的命名開頭習慣小寫,不可以使用數字為開頭,名稱不能用保留關鍵字(int, float....),特殊符號(%,#..... 註一)與空格也是禁止的。另外在Objective-C 中,是區分大小寫的。
- (void)SetName:(NSString *)name;
這是個物件方法,沒有回傳值,方法名稱是SetName:,如果有接受參數必須接著冒號,接受一個NSString參數。
為了維持物件導向的封裝性(Encapsulation),讓外部的類別不能直接存取與修改變數,所以我們不得不設計這麼多的getter and setter,這也是為什麼後來會有@property來減輕工作量的原因。
Wolf.m
#import "Wolf.h" @implementation Wolf -(void)SetName:(NSString *)name { _name = name; } -(NSString *)name { return _name; } -(void)SetAge:(int)age { _age = age; } -(int)age { return _age; } +(void)bray { NSLog(@"Wu Wu.......!!!"); } @end在@implementation與@end中,把宣告的方法都實作出來,這裡可以看到為什麼很多人的習慣是把變數前面加下引號,因為如果不加下引號,會寫成 name = name,容易混淆,可讀性變差。
main.m
#import <Foundation/Foundation.h> #import "Wolf.h" int main(int argc, const char * argv[]) { @autoreleasepool { [Wolf bray]; Wolf *w = [[Wolf alloc]init]; [w SetName:@"BloodX"]; [w SetAge:7]; NSLog(@"%@ is a wolf, and he is %d years old.",[w name],[w age]); } return 0; }
[Wolf bray],類別方法可以直接呼叫,而不需要實體化一個物件。
Wolf *w = [[Wolf alloc] init], 宣告且生成一個物件,alloc 配置一塊記憶體,init初始化。這些方法都是繼承至NSObject。
當然你也可以這樣寫,如果時間多的話。
Wolf *w;
w = [Wolf alloc];
w = [w init];
時間少的話,可以偷懶一下
Wolf *w = [Wolf new];
方法的呼叫是用中括號,你也可以一直刮下去,例如:[[[[Wolf allo ]init ]play ],但可讀性就變差了。
@property and @synthesize
在Objective-C 2.0之後開始可以使用@property來幫忙我們少寫一點getter and setter,使用方式很簡單,在.h 檔中宣告,.m 合成。
Wolf.h
@interface Wolf : NSObject @property NSString *name; -(void)bray; @end
Wolf.m
@implementation Wolf @synthesize name; -(void)bray { NSLog(@"Wooo Wooo...."); }
這樣就幫你設定好並實作出兩個方法,
-(NSString *)name;
-(void)setName;
如果你不想讓別人知道實際修改的是什麼變數,可以改成這樣。
.h
@interface Wolf : NSObject { NSString *name; } @property NSString *secret; -(void)bray; @end
.m
@implementation Wolf @synthesize secret = name; -(void)bray { NSLog(@"Wooo Wooo...."); } @end
. dot operator
方便直接呼叫 getter and setter
Wolf *w = [Wolf new];
w.name = @"Jon"; // 在等號左邊,呼叫setter [w setName:(@"Jon")]
NSLog(@"%@",w.name); // 呼叫getter [w name]
註一:在書中說 $ 字元不可以於命名中使用,不過實際在編譯時卻可以 :) 。
沒有留言:
張貼留言