Objective-C最基礎(chǔ)語(yǔ)法之Class定義
Objective-C最基礎(chǔ)語(yǔ)法之Class定義是本文要介紹的內(nèi)容,Objective-C是面向?qū)ο蟮恼Z(yǔ)言,因此類的定義是基礎(chǔ)中的基礎(chǔ)。Objective-C是C的超級(jí),但是在語(yǔ)法上跟C又有一些不同,尤其是在對(duì)屬性和方法的訪問(wèn)上,有其非常特殊的語(yǔ)法。看過(guò)Objective-C的代碼都知道,里面會(huì)有很多的中括號(hào),這是Objective-C獨(dú)有的。
在Objective-C里面一個(gè)類的構(gòu)成一般由兩部分組成,一個(gè)是成員和方法聲明的頭文件(.h),一個(gè)是類方法實(shí)現(xiàn)的文件(.m)文件。當(dāng)然你也可以把類的聲明寫在.m文件里面,但是這樣就是私有的成員,其他類就不能使用了。類成員的聲明是通過(guò)interface來(lái)實(shí)現(xiàn)的,懂C#的朋友應(yīng)該知道C#里面也有interface,但是Objective-C里面的interfacegen跟C#里面是完全是兩回事,Objective-C里面的interface就是用來(lái)定義一個(gè)類里面有那些屬性和方法的。
一個(gè)類的方法有兩種,一種是類方法,一種是實(shí)例方法。類方法有點(diǎn)像靜態(tài)方法,它屬于一個(gè)類,而不是屬于一個(gè)類的實(shí)例。而實(shí)例方法就是屬于一個(gè)類的實(shí)例的方法。類方法在定義的時(shí)候前面用“+”號(hào)標(biāo)識(shí),實(shí)例方法前面則用“-”號(hào)標(biāo)識(shí)。比如:
- + (id)allObjective-C;//這是一個(gè)類方法
- (void)doSomething;//這是一個(gè)實(shí)例方法
在調(diào)用的時(shí)候使用中括號(hào)的語(yǔ)法,比如:
- MyClass *class = [MyClass allObjective-C];//調(diào)用類方法,分配內(nèi)存
- [class doSomething];//調(diào)用實(shí)例方法,實(shí)現(xiàn)某些功能
首先看一個(gè)完整的類的定義和實(shí)現(xiàn)的例子。
.h文件的代碼為:
- @interface Person:NSObject{
- NSUInteger age;
- NSString *name;
- }
- @property (nonatomic, assign)NSUInteger age;
- @property (nonatomic,retain)NSString *name;
- + (Person *)person;
- - (id)init;
- - (void)setAge:(NSUInteger)theAge;
- - (NSUInteger)age;
- - (void)vote;
- @end
.m文件的代碼:
- #import "Person.h"
- @interface Person ()
- - (BOOL)canVote;
- @end
- @implementation Person
- @synthesize name;
- - (void)setAge:(NSUInteger)theAge{
- age = theAge;
- }
- - (NSUInteger)age{
- return age;
- }
- - (id)init{
- if (self = [super init]){
- age = 0;
- name = @"";
- }
- return self;
- }
- - (BOOL)canVote{
- return age >= 18;
- }
- - (void)vote{
- //do something
- }
- @end
上面是一個(gè)比較完整的定義類的例子,首先在頭文件里面定義了兩個(gè)字段,叫age和name;還有兩個(gè)屬性,也叫age和name,還有一個(gè)初始化的方法和一個(gè)實(shí)例方法。很多朋友剛接觸Objective-C的時(shí)候可能不理解,怎么字段和屬性的名字是一樣的?有什么不同么?是的,在Objective-C里面字段和屬性的名字是可以一樣的,但二者是不同的東西。一般來(lái)說(shuō)一個(gè)類的頭文件聲明的結(jié)構(gòu)是這樣的:
- @interface 類名{
- 字段聲明
- }
- 屬性聲明
- 方法聲明
- @end
字段是私有的,在類外部不能使用。必須使用屬性,外部才能使用。什么是屬性?其實(shí)屬性就是對(duì)一個(gè)字段的get和set方法。在C#里面我們可以很方便地使用get和set訪問(wèn)器,但是在Objective-C里面要分別定義。比如上面的例子就是定義了一個(gè)setAge的set方法和一個(gè)叫age的get方法 。
而如果我們并不需要在屬性的get或者set方法中做任何的操作,還要自己寫這么多代碼實(shí)在是有些麻煩。Objective-C里有一種快速定義屬性的方法,就是使用 synthesize。synthesize后面跟著屬性名,編譯器就會(huì)自動(dòng)幫你添加一個(gè)屬性,而不用自己去寫get和set方法了。那如果你要定義的屬性是只讀的或者有其他特性,該怎么辦呢?看頭文件里面定義屬性的時(shí)候,只要做一些說(shuō)明就好了。
比如上面例子中的name屬性,在前面就有(nonatomic,retain)相關(guān)的說(shuō)明。這些說(shuō)明是跟內(nèi)存管理和訪問(wèn)權(quán)限有關(guān)的,比如添加了retain說(shuō)明,就類似于name = [value retail],也就是說(shuō)在給這個(gè)屬性賦值的時(shí)候就會(huì)把retain count增加一。還有其他的說(shuō)明比如readonly等,不一一列舉。一般來(lái)說(shuō),給基本類型比如NSInteger的屬性添加的說(shuō)明有nonatomic, assign,而給引用類型的屬性添加唉的有nonatomic,retain。
除了定義字段和屬性外,我們還需要定義方法。定義方法比較簡(jiǎn)單,只要區(qū)分好類方法和實(shí)例方法就好了。還有一點(diǎn)需要注意的是,在Objective-C中一個(gè)方法的名稱是包含冒號(hào)的,比如age屬性的set方法的完整的名稱是setAge:,而不是setAge。Objective-C里方法的定義比較詭異,它允許將一個(gè)方法的名稱和參數(shù)的名稱混合在一起。比如在C#中我定義一個(gè)方法:
- void SetPosition(int x,int y)
- {}
- 在Objective-C中就會(huì)變成這樣:
- - (void)setPositionX:(NSInteger) x Y:(NSInteger)y{
- }
這個(gè)時(shí)候完整的方法名是“setPositionX:Y:”,方法名和參數(shù)名是混合在一起的,各參數(shù)之間用空格分開,參數(shù)名后面緊跟著冒號(hào),并用小括號(hào)擴(kuò)起參數(shù)的類型(別忘了引用類型要添加*以表示指針),最后跟著形參的名字。
還有一點(diǎn)要注意的是,形參的名字不要和屬性或字段的名字重復(fù)了,否則會(huì)有編譯警告,說(shuō)局部變量覆蓋了全局的變量。剛接觸Objective-C的時(shí)候?qū)@個(gè)可能會(huì)比較不習(xí)慣,不過(guò)到后來(lái)感覺(jué)還蠻舒服的。
.m文件里面的代碼是方法的具體實(shí)現(xiàn),這是對(duì)外不可見的。一個(gè)典型的m文件的內(nèi)容為:
#import "頭文件.h"//系統(tǒng)自帶的請(qǐng)用<>而不是雙引號(hào),不解釋
- @implementation 類名{
- //方法的具體實(shí)現(xiàn)
- }
方法的實(shí)現(xiàn)就不需要過(guò)多的解釋了。在上面的例子當(dāng)中還額外多了一些東西
- @interface Person ()
- - (BOOL)canVote;
- @end
這又是干什么的了?在Objective-C中這叫“擴(kuò)展”。所謂的擴(kuò)展,其實(shí)就是對(duì)一個(gè)類的方法或?qū)傩赃M(jìn)行擴(kuò)展。原來(lái)的類中沒(méi)有的方法或?qū)傩裕覀兛梢院芊奖愕眠M(jìn)行擴(kuò)展。但是一定要注意,在擴(kuò)展中只能擴(kuò)展屬性和方法,如果你想添加字段,那就會(huì)編譯錯(cuò)誤。一個(gè)典型的擴(kuò)展的寫法跟interface比較類戲,形如:
- @interfae 類名(可以添加一些說(shuō)明性的文字,也可以留空)
- //定義屬性和方法,但是不能添加字段,因此那一對(duì)大括號(hào)不能有
- @end
擴(kuò)展可以是公開的,也可以是私有的,就看你在哪里定義。這里我定義在m文件里面,自然就是私有的了,如果定義在頭文件里面,那么就是公有的。
interface可以分開多出定義,同樣的implementation一個(gè)類也可以寫多次,寫多次的好處就是調(diào)理比較清晰,提高代碼的可讀性。比如可以把功能相關(guān)的一些代碼寫在一個(gè)
- @ implementation@end中
然后另外一些代碼寫在別的地方。
在Objective-C中定義一個(gè)類的最基礎(chǔ)的語(yǔ)法大概就是這么多。
小結(jié):Objective-C最基礎(chǔ)語(yǔ)法之Class定義的內(nèi)容介紹完了,希望通過(guò)本文的學(xué)習(xí)能對(duì)你有所幫助!