objective-c代碼學(xué)習(xí)大綱_第1頁
objective-c代碼學(xué)習(xí)大綱_第2頁
objective-c代碼學(xué)習(xí)大綱_第3頁
objective-c代碼學(xué)習(xí)大綱_第4頁
已閱讀5頁,還剩70頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Objective-C代碼學(xué)習(xí)大綱(1)2011-05-1114:06佚名otierney我要評論(4)字號:TT

收藏本文為臺灣出版的《Objective-C學(xué)習(xí)大綱》的翻譯文檔,系統(tǒng)介紹了Objective-C代碼,很多名詞為臺灣同胞特指詞匯,在學(xué)習(xí)時仔細研讀才能體會。AD:2013大數(shù)據(jù)全球技術(shù)峰會低價搶票中所有這篇初學(xué)者指南的源始碼都可以由objc.tar.gz下載。這篇教學(xué)中的許多範例都是由SteveKochan在ProgramminginObjective-C.ー書中撰寫。如果你想得到更多詳細資訊及範例,請直接參考該書。這個網(wǎng)站上登載的所有範例皆經(jīng)過他的允許,所以請勿復(fù)製轉(zhuǎn)載。設(shè)定環(huán)境Linux/FreeBSD:安裝GNUStep為了編譯GNUstep應(yīng)用程式,必須先執(zhí)行位于/usr/GNUstep/System/Makefiles/GNUstep.sh的GNUstep.sh這個檔案。這個路徑取決于你的系統(tǒng)環(huán)境,有些是在/usr,some/usr/lib,有些是/usr/localo如果你的shell是以csh/tcsh為基礎(chǔ)的shell,則應(yīng)該改用GNUStep.csho建議把這個指令放在.bashrc或,cshrc中。MacOSX:安裝XCodeWindowsNT5.X:安裝cygwin或mingw?然后安裝GNUStep

前百這篇教學(xué)假設(shè)你已經(jīng)有一些基本的c語言知識,包括C資料型別、什么是函式、什么是回傳值、關(guān)于指標的知識以及基本的C語言記憶體管理。如果您沒有這些背景知識,我非常建議你讀ー讀K&R的書:TheCProgrammingLanguage(譯注:臺灣出版書名為C程式語言第二版)這是C語言的設(shè)計者所寫的書。Objective-C?是C的衍生語言,繼承了所有C語言的特性。是有一些例外,但是它們不是繼承于C的語言特性本身。nil:在C/C++你或許曾使用過NULL,而在Objective-C中則是nil。不同之處是你可以傳遞訊息給nil(例如[nilmessage];)?這是完全合法的,然而你卻不能對NULL如法炮製。BOOL:C沒有正式的布林型別,而在Objective-C中也不是「真的」有。它是包含在Foundationclasses(基本類別庫)中(即importNSObject.h;nil也是包括在這個標頭檔內(nèi))。BOOL在Objective-C中有兩種型態(tài):YES或N0,而不是TRUE或FALSE〇#importvsttinclude:就如同你在helloworld範例中看到的,我們使用了#importoftimport由gcc編譯器支援。我并不建議使用ttinclude,#import基本上跟,h檔頭尾的ttifndef#define#endif相同。許多程式員們都同意,使用這些東西這是十分愚蠢的。無論如何,使用#timport就對了。這樣不但可以避免麻煩,而且萬一有一天gcc把它拿掉了,將會有足夠的Objective-C程式員可以堅持保留它或是將它放冋來。偷偷告訴你,Apple在它們官方的程式碼中也使用了#importB所以萬一有一天這種事真的發(fā)生,不難預(yù)料Apple將會提供ー個支援ftimport的gcc分支版本。在Objective-C中,method及message這兩個字是可以互換的。不過messages擁有特別的特性,ー個message可以動態(tài)的轉(zhuǎn)送給另ー個物件。在Objective-C中,嗯叫物件上的ー個訊息并不一定表示物件真的會實作這個訊息,而是物件知道如何以某種方式去實作它,或是轉(zhuǎn)送給知道如何實作的物件。編譯helloworldhello.m#main(intargcrconstchar*argv[]){.printf("hell〇world\nn);.return0;}輸出helloworld在Objective-C中使用#import代替#includeObjective-C的預(yù)設(shè)副檔名是.m

Objective-C代碼學(xué)習(xí)大綱(2)2011-05-1114:06佚名otierney我要評論(4)字號:TT

收藏Q本文為臺灣出版的《Objective-C學(xué)習(xí)大綱》的翻譯文檔,系統(tǒng)介紹了Objective-C代碼,很多名詞為臺灣同胞特指詞匯,在學(xué)習(xí)時仔細研讀才能體會。AD:2013大數(shù)據(jù)全球技術(shù)峰會低價搶票中創(chuàng)建classes?interface..Fraction.h.#import.@interfaceFraction:NSObject{.intnumerator;intdenominator;}. -(void)print;--(void)setNumerator:(int)n;-(void)setDenominator:(int)d;-(int)numerator;. -(int)denominator;.@endNSObject:NeXTStepObject的縮寫。因為它已經(jīng)改名為OpenStep,所以這在今天已經(jīng)不是那么有意義了。繼承(inheritance)以Class:Parent表示,就像上面的Fraction:NSObject〇夾在@interfaceClass:Parent{....}中的稱為instancevariableso沒有設(shè)定存取權(quán)限(protected,public,private)時,預(yù)設(shè)的存取權(quán)限為protectedo設(shè)定權(quán)限的方式將在稍后說明。Instancemethods跟在成員變數(shù)(即instancevariables)后。格式為:scope(returnType)methodName:(parameterIType)parameterIName;scope有class或instance兩種。1nstancemethods以ー開頭,classlevelmethods以+開頭。Interface以一?個@end作為結(jié)束。?implementation.Fraction.m.

#import@implementationFraction(void)print{. printf(n%i/%iM,numeratorrdenominator);TOC\o"1-5"\h\z). -(void)setNumerator: (int) n {. nnumerator=n;. }. -(void)setDenominator: (int) d{. ddenominator=d;}. -(int) denominator {. return denominator;. }. "(int) numerator {. return numerator;). @endImplementation以?implementationClassName開始,以@end結(jié)束。Implementation以4..9.101112131415161718192021222324252627282930313233343536373839Implement定義好的methods的方式,跟在interface中宣告時很近似。把它們湊在ー起main.m.#import..#importnFraction.hintmain(intargc,constchar*argv[]){//createanewinstanceinit];Fraction*fracinit];//setthevalues.[fracsetNumerator:1];[fracsetDenominator:3];//printitprintf("Thefractionis:”);[fracprint];.. printf(“ヽn");//freememory[fracrelease];return0;}outputThefractionis:1/33.Fraction*frac[[Fractionalloc]init];這行程式碼中有很多重要的東西。在Objective-C中惣叫methods的方法是[objectmethod],就像C++的object-〉method()。Objective-C沒有value型別。所以沒有像C++的Fractionfrac;frac.print():這類的東西。在Objective-C中完全使用指標來處理物件。這行程式碼實際上做了兩件事:[Fractionalloc]嗯叫了Fractionclass的allocmethodo這就像malloc記憶體,這個動作也做了一樣的事情。[objectinit]是ー個建構(gòu)子(constructor)惣叫,負責(zé)初始化物件中的所有變數(shù)。它惣叫了[Fractionalloc]傳回的instance上的initmethodo這個動作非常普遍,所以通常以一行程式完成:Object*var=[[Objectalloc]init];[fracsetNumerator:1]非常簡單。它嗯叫了frac上的setNumeratormethod并傳入1為參數(shù)。如同每個C的變體,Objective-C也有一個用以釋放記憶體的方式:releaseo它繼承自NSObject,這個method在之后會有詳盡的解說。Objective-C代碼學(xué)習(xí)大綱(3)2011-05-1114:06佚名otierney我要評論(4)字號:TT本文為臺灣出版的《Objective-C學(xué)習(xí)大綱》的翻譯文檔,系統(tǒng)介紹了Objective-C代碼,很多名詞為臺灣同胞特指詞匯,在學(xué)習(xí)時仔細研讀才能體會。AD:2013大數(shù)據(jù)全球技術(shù)峰會低價搶票中詳細說明...多重參數(shù)目前為止我還沒展示如何傳遞多個參數(shù)。這個語法乍看之下不是很直覺,不過它卻是來自一個十分受歡迎的Smalltalk版本。Fraction,h.....-(void)setNumerator:(int)nandDenominator:(int)d;.....Fraction.m??.. -(void)setNumerator:(int)nandDenominator:(int)d{. nnumerator=n;. ddenominator=d;}.... main.m.#import

2627282930313233343536373839404142434445464748495051525354555657585960616263646566676869?import"Fraction.hnintmain(intargc,constchar*argv[]){//createanewinstanceFraction*frac=[[Fractionalloc]init];Fraction*frac2=[[Fractionalloc]init];//setthevalues[fracsetNumerator:1];[fracsetDenominator:3];//combinedset[frac2setNumerator:1andDenominator:5];//printitprintf("Thefractionis:");[fracprint];printf("\n");//printitprintf("Fraction2is:");[frac2print];printf("\n");//freememory[fracrelease];[frac2release];return0;

}outputThefractionis:1/3.Fraction2is:1/5這個method實際上叫做setNumerator:andDenominator:加入其他參數(shù)的方法就跟加入第二個時一樣,即method:label1:label2:label3:,而惣叫的方法是[objmethod:param1label1:param2label2:param3label3:param4]Labels是非必要的,所以可以有一個像這樣的method:method:::,簡單的省略label名稱,但以:區(qū)隔參數(shù)。并不建議這樣使用。建構(gòu)子(Constructors)!,Fraction.h.......-(Fraction*)initWithNumerator:(int)ndenominator:(int)d;.フ????.Fraction.m??.. -(Fraction*)initWithNumerator:(int)ndenominator:(int)d{.self[superinit]self[superinit];

17.18.if(self){19.20.[selfsetNumerator:nandDenominator:d];21.22.}23.24.returnself;25.26.}27.28.???29.30.main.m31.32.#import33.34.?importnFraction.h,main(intargc,constchar*argv[]){37.38.//createanewinstance39.40.Fraction*frac=[[Fractionalloc]init];41.42.Fraction*frac2=[[Fractionalloc]init];43.Fraction*frac3=[[Fractionalloc]initWithNumerator:344.denominator:10];45.46.//setthevalues47.48.[fracsetNumerator:1];49.50.[fracsetDenominator:3];51.52.//combinedset53.54.[frac2setNumerator:1andDenominator:5];55.56.//printit57.58.printf("Thefractionis:");59.[fracprint];

6〇,61.printf(M\nn);62.63.printf("Fraction2is:n);64.65.[frac2print];66.67.printf(n\nn);68.69.printf("Fraction3is:”);70.71.[frac3print];72.73.printf("\n");74.75.//freememory76.77.[fracrelease];78.79.[frac2release];80.81.[frac3release];82.83.return0;84.85.}outputThefractionis:1/3.Fraction2is:1/5.Fraction3is:3/10?interface裡的宣告就如同正常的函式。?implementation使用了一個新的關(guān)鍵字:super如同Java,Objective-C只有一個parentclass(父類別)。使用[superinit]來存取Superconstructor?這個動作需要適當?shù)睦^承設(shè)計。你將這個動作回傳的instance指派給另一新個關(guān)鍵字:self。Self很像C++與Java的this指標。if(self)跟(self!=nil)ー樣,是為了確定superconstructor成功傳回了一個新物件。nil是Objective-C用來表達C/C++中NULL的方式,可以引入NSObject來取得。當你初始化變數(shù)以后,你用傳回self的方式來傳回自己的位址。預(yù)設(shè)的建構(gòu)子是-(id)inito技術(shù)上來說,Objective-C中的建構(gòu)子就是ー個"init"method,而不像C++與Java有特殊的結(jié)構(gòu)。存取權(quán)限預(yù)設(shè)的權(quán)限是0protectedJava實作的方式是在methods與變數(shù)前面加上public/private/protected修飾語,而Objective-C的作法則更像C++對于instancevariable(譯注:C++術(shù)語一般稱為datamembers)的方式。!,Access,h#import.@interfaceAccess:NSObject{.@public

9.intpublicVar;10.11.12.@privateVar;15.16.intprivateVar2;17.18.@protectedVar;21.22.}23.24.@end25.26.Access.m27.28.#import"Access.hn29.30.@implementationAccess31.32.@end33.34.main.m35.36.#import"Access.hn37.38.?main(intargc,constchar*argv[]){41.42.Access*a=[[Accessalloc]init];43.44.//works45.46.a->publicVar=5;47.48.printf("publicvar:%i\n"za->publicVar);49.50.//doesn1tcompile51.//a->privateVar=10;. //printf("privatevar:%i\nnra->privateVar);[arelease];. return0;)outputpublicvar:5如同你所看到的,就像C++中private:[listofvars]public:[listofvars]的格式,它只是改成了@private,?protected,等等。ClasslevelaccessClassA.h.,#import.staticintcount;.@interfaceClassA:NSObject..+(int)initCount;+(void)initialize;@end.ClassA.m. #import"ClassA.hH@implementation ClassA-(id)init{. self=[superinit];

2425242526272829303132333435363738394041424344454647484950515253545556575859returnself;}+(int)initCount{returncount;}+(void)initialize{count=0;)@endmain.m#import"ClassA.hH#importintmain(intargc,constchar*argv[]){ClassA*cl=[[ClassAalloc]init];ClassA*c2=[[ClassAalloc]init];//printcount606162636465ClassA*c3[[ClassAalloc]init];//printcountagainprintf("ClassAcount:%i\n”,606162636465ClassA*c3[[ClassAalloc]init];//printcountagainprintf("ClassAcount:%i\n”,[ClassAinitCount]);[clrelease];[c2release];[c3release];return0;.}output.ClassAcount:2..ClassAcount:3staticintcount=0;這是classvariable宣告的方式。其實這種變數(shù)擺在這裡并不理想,比較好的解法是像Java實作staticclassvariables的方法。然而,它確實能用。+(int)initCount:這是回傳count值的實際methodo請注意這細微的差別!這裡在type前面不用減號一而改用加號+。加號+表示這是ー個classlevelfunction。(譯注:許多文件中,classlevelfunctions被稱為classfunctions或classmethod)存取這個變數(shù)跟存取一般成員變數(shù)沒有兩樣,就像ClassA中的count++用法。+(void)initializemethodis在Objective-C開始執(zhí)行你的程式時被惣叫,而且它也被每個class惣叫。這是初始化像我們的count這類classlevelvariables的好地方

..9.1011121314151617181920212223242526272829303132333435363738異常情況(Exceptions)注意:異常處理只有MacOSX10.3以上オ支援。CupWarningException.h#import@interfaceCupWarningException:NSException@endCupWarningException.m. #importHCupWarningException.hH. @implementationCupWarningException. @end. CupOverflowException.h. #import. @interfaceCupOverflowException:NSException. @end. CupOverflowException.m. #importMCupOverflowException.hM. @implementationCupOverflowException. @endCup?h#import@interfaceCup:NSObject{

39.40.intlevel;41.42.)43.44.-(int)level;8.-(void)setLevel:(int)1;-(void)fill;49.50.-(void)empty;51.52.-(void)print;53.54.@end55.56.Cup.m0.#importnCup.hM?importnCupOverflowException.hH61.62.?import"CupWarningException.h"63.64.?import8.69.70.?import@implementationCup-(id)init{71.72.self=[superinit];73.74.if(self){75.76.[selfsetLevel:0];77.78.}2.returnself;}83.84.-(int)level{85.86.returnlevel;87.88.}89.90.-(void)setLevel:(int)1{91.92.llevel=1;93.94.if(level>100){95.96.//throwoverflow97.98.NSException*e=[CupOverflowException99.100.exceptionWithName:@HCupOverflowExceptionn101.102.reason:@"Thelevelisabove100n103.104.userlnfo:nil];105.106.@throwe;107.108.}elseif(level>=50){109.110.//throwwarning111.112.NSException*e=[CupWarningException113.114.exceptionWithName:@MCupWarningExceptionn115.116.reason:@"Thelevelisaboveorat50"117.118.userinfo:nil];119.120.@throwe;121.122.}elseif(level<0){123.124.//throwexception125.126.NSException*e=[NSException127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170exceptionWithName:@MCupUnderflowException11reason:@"Thelevelisbelow〇”userinfo:nil];@throwe;})(void)fill{[selfsetLevel:level+10];}(void)empty{[selfsetLevel:level-10];}(void)print{printf("Cuplevelis:%i\n",level);}@endmain.m#import"Cup.h"import"CupOverflowException.h"import"CupWarningException.h"import?import

171.#import172.173.#main(intargc,constchar*argv[]){176.177.NSAutoreleasePool*pool=[[NSAutoreleasePool]init];178.179.Cup*cup=[[Cupalloc]init];180.181.inti;182.183.//thiswillwork184.185.for(i=0;i<4;i++){186.187.[cupfill];188.189.[cupprint];190.191.}192.193.//thiswillthrowexceptions194.195.for(i=0;i<7;i++){196.197.@try(198.199.[cupfill];200.201.}@catch(CupWarningException*e){202.203.printf("%s:",[[ename]cString]);204.205.}@catch(CupOverflowException*e){206.207.printf("%s:",[[ename]cString]);208.209.}@finally{210.211.[cupprint];212.213.}alloc17.217.//throwagenericexception19.220.@try{[cupsetLevel:-1];}@catch(NSException*e){[ereason]printf("%s:%s\n”,[[ename]cString],[[ereason]cString]);}//freememory[cuprelease];[poolrelease];.}output1.Cuplevelis:102.3.Cuplevelis:204.5.Cuplevelis:306.7.Cuplevelis:408.9.CupWarningException:Cuplevelis:5010.11121314151617CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:CupWarningException:Cuplevelis:60708090CupWarningExceptionCupWarningException:Cuplevelis:100CupOverflowException:Cuplevelis:110. CupUnderflowException:Thelevelisbelow0NSAutoreleasePool是ー個記憶體管理類別?,F(xiàn)在先別管它是干嘛的。Exceptions(異常情況)的丟出不需要擴充(extend)NSException物件,你可簡單的用id來代表它:?catch(ide){...}還有一個finally區(qū)塊,它的行為就像Java的異常處理方式,finally區(qū)塊的內(nèi)容保證會被惣叫。Cup.m裡的0/?CupOverflowException?是ー個NSString常數(shù)物件。在Objective-C中,?符號通常用來代表這是語言的衍生部分。C語言形式的字串(Cstring)就像C/C++ー樣是"Stringconstant"的形式,型別為char*oObjective-C代碼學(xué)習(xí)大綱(4)2011-05-1114:06佚名otiemey我要評論(4)字號:TlT

收藏エ3 4- Iロ F本文為臺灣出版的《Objective-C學(xué)習(xí)大綱》的翻譯文檔,系統(tǒng)介紹了 :Objective-C代碼,很多名詞為臺灣同胞特指詞匯,在學(xué)習(xí)時仔細研讀才能j體會。 :AD:2013大數(shù)據(jù)全球技術(shù)峰會低價搶票中セ繼承、多型(Inheritance,Polymorphism)以及其他物件導(dǎo)向功能id型別Objective-C有種叫做id的型別,它的運作有時候像是void*,不過它卻嚴格規(guī)定只能用在物件。Objective-C與Java跟C++不ー樣,你在嗯叫ー個物件的method時,并不需要知道這個物件的型別。當然這個method一定要存在,這稱為Objective-C的訊息傳遞。!,Fraction?h..#import.@interfaceFraction:NSObject{intnumerator;intdenominator;}-(Fraction*)initWithNumerator:(int)ndenominator:(int)d;.. -(void)print;. -(void)setNumerator:(int)d;-(void)setDenominator:(int)d;-(void)setNumerator:(int)nandDenominator:(int)d;. -(int)numerator;.-(int)denominator;@end

29.Fraction.m.?importHFraction.hn?import@implementationFraction-(Fraction*)initWithNumerator:(int)ndenominator(int)d(self=[superinit];if(self){[selfsetNumerator:nandDenominator:d];.)returnself;}-(void)print{printf(n%i/%inznumerator,denominator);...}(void)setNumerator:(int)nnnumerator=n;}(void)setDenominator:(int)ddenominator=d;}(void)setNumerator:(int)n{d(andDenominator:(int)d{71.72.nnumerator=n;73.74.ddenominator=d;75.76.}77.78.-(int)denominator{79.80.returndenominator;81.82.)83.84.-(int)numerator{85.86.returnnumerator;87.88.}89.90.@end91.92.Complex.h93.94.#import95.96.@interfaceComplex:NSObject{97.98.doublereal;99.100.doubleimaginary;101.102.}103.-(Complex*)initWithReal:(double)randlmaginary:(double)i;104.105.106.-(void)setReal:(double)r;107.108.-(void)setImaginary:(double)i;109.i;110.-(void)setReal:(double)randlmaginary:(double)111.112.-(double)real;113.114.-(double)imaginary;115.116.-(void)print;117.118.@end22.Complex,m#import"Complex.h"123.124.#import125.126.@implementationComplex127.-(Complex*)initWithReal:(double)randlmaginary:(double)i{34.135.136.self=[superinit];if(self){[selfsetReal:randlmaginary:i];)40.141.142.returnself;}-(void)setReal:(double)r{143.144.rreal=r;145.146.}147.148.-(void)setImaginary:(double)i{149.150.iimaginary=i;151.152.153.i(}-(void)setReal:(double)randlmaginary:(double)

155.156.rreal=r;157.158.iimaginary=i;159.160.}161.162.-(double)real{163.164.returnreal;165.166.)167.168.-(double)imaginary{169.170.returnimaginary;171.172.}173.174.-(void)print{175.176.printf("%_f+%_fiM,real,imaginary);177.178.)179.180.@end181.182.main.m183.184.#import185.186.#import"Fraction.hn187.188.#import"Cmain(intargc,constchar*argv[]){191.192.//createanewinstance193.Fraction*frac=[[Fractionalloc]initWithNumerator:1194.denominator:10];195.Complex*comp=[[Complexalloc]initWithReal:10andlmaginary:15];

197.198.idnumber;199.200.//printfraction201.202.number=frac;203.204.printf("Thefractionis:");205.206.[numberprint];207.208.printf("\n");209.210.//printcomplex211.212.number=comp;213.214.printf("Thecomplexnumberis:");215.216.[numberprint];217.218.printf("\n");219.220.//freememory221.222.[fracrelease];223.224.[comprelease];225.226.return0;227.}outputThefractionis:1/10Thecomplexnumberis:10.000000+15.OOOOOOi這種動態(tài)連結(jié)有顯而易見的好處。你不需要知道你嗯叫method的那個東西是什么型別,如果這個物件對這個訊息有反應(yīng),那就會喚起這個methodo..9.1011121314151617181920212223242526272829303132333435這也不會牽涉到ー堆繁瑣的轉(zhuǎn)型動作,比如在Java裡嗯叫一個整數(shù)物件的,intValue()就得先轉(zhuǎn)型,然后才能惣叫這個methodo繼承(Inheritance)Rectangle.h#import@interfaceRectangle:NSObject{intwidth;intheight;}(Rectangle*)initWithWidth:(int)wheight:(int)h;(void)setwidth:(int)w;(void)setHeight:(int)h;(void)setwidth:(int)wheight:(int)h;(int)width;(int)height;(void)print;@endRectangle.m#import"Rectangle?h”#import@implementationRectangle

36.37.-(Rectangle*)initWithWidth:(int)wheight:h{38.39.self=[superinit];40.41.if(self){42.43.[selfsetwidth:wheight:h];44.45.)46.47.returnself;48.49.}50.51.-(void)setwidth:(int)w{52.53.wwidth=w;54.55.}56.57.-(void)setHeight:(int)h{58.59.hheight=h;60.61.)62.63.-(void)setwidth:(int)wheight:(int)h{64.65.wwidth=w;66.67.hheight=h;68.69.}70.71.-(int)width{72.73.returnwidth;74.75.)76.77.-(int)height{78.(int)

79.80.returnheight;81.82.)83.84.-(void)print{85.printf("width=%i,height=%i”,width,height);86.87.88.)89.90.@end91.92.Square.h93.94.#import"Rectangle.h"95.96.@interfaceSquare:Rectangle97.98.-(Square*)initWithSize:(int)s;99.100.-(void)setSize:(int)s;101.102.-(int)size;103.104.@end105.106.Square.m107.108.#import"Square.h"109.110.@implementationSquare111.112.-(Square*)initWithSize:(int)s{113.114.self=[superinit];115.116.if(self){117.118.[selfsetSize:s];119.120.}121.returnself;122.123. )124.125.126.-(void)setsize:(int)s{127.128.width=s;129.130.height=s;131.132.}133.134.-(int)size{135.136.returnwidth;137.138.)139.140.-(void)setwidth:(int)w{141.142.[selfsetsize:w];143.144.}145.146.-(void)setHeight:(int)h{147.148.[selfsetsize:h];149.150.}151.152.@end153.154.main.m155.156.#importHSquare.hM157.158.?import"Rectangle.h"159.160.?main(intargc,constchar*argv[]){163.Rectangle*rec=[[Rectanglealloc]initWithWidth:10height:20];165.Square*sq=[[Squarealloc]initWithSize:166.167.//printem168.169.printf("Rectangle:");170.171.[recprint];172.173.printf("\n");174.175.printf("Square:");176.177.[sqprint];178.179.printf("\n");180.181.//updatesquare182.183.[sqsetwidth:20];184.185.printf("Squareafterchange:");186.187.[sqprint];188.189.printf("\n");190.191.//freememory192.193.[recrelease];194.195.[sqrelease];196.197.return0;198.199.}output15];Rectangle:width=10,height=20.Square:width=15,height=15Squareafterchange:width=20,height=20繼承在Objective-C裡比較像Java。當你擴充你的superclass(所以只能有一個parent)?你想自訂這個superclass的method?只要簡單的在你的childclassimplementation裡放上新的實作內(nèi)容即可。而不需要C++裡呆呆的virtualtable〇這裡還有一個值得玩味的地方,如果你企圖像這樣去惣叫rectangle的constructor:Square*sq=[[Squarealloc]initWithWidth:10height:15],會發(fā)生什么事?答案是會產(chǎn)生一個編譯器錯誤。因為rectangleconstructor回傳的型別是Rectangle*,而不是Square*,所以這行不通。在某種情況下如果你真想這樣用,使用id型別會是很好的選擇。如果你想使用parent的constructor,只要把Rectangle?回傳型別改成id即可。動態(tài)識別(Dynamictypes)這裡有一些用于Objective-C動態(tài)識別的methods(說明部分採中英并列,因為我覺得英文比較傳神,中文怎么譯都怪):1.-(BOOL)isKindOfClass:classObjisobjectadescendentormemberofclassObj此物件是否是classObj的子孫或ー員1.-(BOOL)isMemberOfClass:classObjisobjectamemberofclassObj此物件是否是classObj的一員1.-(BOOL)respondsToSelector:selectordoestheobjecthaveamethodnamedspecifiecbytheselector此物件是否有叫做selector的method+(BOOL)instancesRespondToSelector:selectordoesanobjectcreatedbythisclasshavetheabilitytorespondtothespecifiedselector此物件是否是由有能力回應(yīng)指定selector的物件所產(chǎn)生-(id)performSelector:selectorinvokethespecifiedselectorontheobject喚起此物件的指定selector所有繼承自NSObject都有一個可回傳ー個class物件的classmethodo這非常近似于Java的getClass()methodo這個class物件被使用于前述的methods中。Selectors在Objective-C用以表示訊息。下ー個範例會秀出建立selector的語法。!,main.m..#importnSquare.hH..#import"Rectangle?h”.#main(intargc,constchar*argv[]){Rectangle*rec=[[Rectanglealloc]initWithWidth:10height:20];Square*sq=[[Squarealloc]initWithSize:15];.//isMemberOfClass. //true

192021222324252627282930313233343536373839404142434445464748495051525354555657YES)if([sqisMemberOfClass:[Squareclass]]printf(nsquareisamemberofsquareclass\nM);YES)}//falseif([sqisMemberOfClass:[Rectangleclass]]==YESprintf(Msquareisamemberofrectangleclass\nM))//falseif([sqisMemberOfClass:[NSObjectclass]]==YESprintf(Msquareisamemberofobjectclass\nM);}//isKindOfClass//trueif([sqisKindOfClass:[Squareclass]]==YES){printf(Msquareisakindofsquareclass\nn);}//trueif([sqisKindOfClass:[Rectangleclass]]==YES)printf(Msquareisakindofrectangleclass'n");

//trueif([sqisKindOfClass:[NSObjectclass]]==YES)(printf(Msquareisakindofobjectclass\nn);}//respondsToSelector//trueif([sqrespondsToSelector:@selector(setsize:)]==YES){printf(nsquarerespondstosetsize:method'n");}//falseif([sqrespondsToSelector:@selector(nonExistant)]==YES){printf(nsquarerespondstononExistantmethod"")J)IItrueif([SquarerespondsToSelector:?selector(alloc)]==YES){printf("squareclassrespondstoallocmethod\n")t}5859606162636465666768697071727374757677787980818283848586878889909192939495//instancesRespondToSelector//false7.square.square.square.square.squareif([RectangleinstancesRespondToSelector:@selector(setsize:)]==YES){98.99. printf(Hrectangleinstancerespondstosetsize:method\n”);03. //true104.if([SquareinstancesRespondToSelector:@selector(setSize:)]==YES){.printf(nsquareinstancerespondstosetSize:method\nM);}//freememory[recrelease];.[sqrelease];return0;118.)outputisamemberofsquareclassisakindofsquareclassisakindofrectangleclassisakindofobjectclassrespondstosetSize:methodsquareclassrespondstoallocmethodsquareinstancerespondstosetsize:methodCategories當你想要為某個class新增methods?你通常會擴充(extend,即繼承)它。然而這不一定是個完美解法,特別是你想要重寫ー個class的某個功能,但你卻沒有姬始碼時。Categories允許你在現(xiàn)有的class加入新功能,但不需要擴充它。Ruby語言也有類似的功能。FractionMath.h..#import"Fraction?h”..@interfaceFraction(Math).-(Fraction*)add:(Fraction*)f;.-(Fraction*)mul:(Fraction*)f;-(Fraction*)div:(Fraction*)f;-(Fraction*)sub:(Fraction*)f;.@endFractionMath.m. #import"FractionMath.h"@implementationFraction (Math)-(Fraction*)add:(Fraction*> f{.return[[Fractionalloc]initWithNumerator:numerator*[fdenominator]+. denominator*[fnumerator]9. denominator:denominator*[fdenominator]];30.

3132333435363738394041424344454647484950515253545556575859606162636465666768697071-(Fraction*)mul:(Fraction*)f{return[[Fractionalloc]initWithNumerator:numerator*[fnumerator]denominator:denominator*[fdenominator]];)(Fraction*)div:(Fraction*)f{return[[Fractionalloc]initWithNumerator:numerator*[fdenominator]denominator:denominator*[fnumerator]];)(Fraction*)sub:(Fraction*)f{return[[Fractionalloc]initWithNumerator:numerator*[fdenominator]-denominator*[fnumerator]denominator:denominator*[fdenominator]];}@endmain.m?import?import"Fraction.h"import"FractionMath?h”intmain(intargc,constchar*argv[]){//createanewinstance

Fraction*fracl=[[Fractionalloc]initWithNumerator:1denominator:3];. Fraction*frac2=[[Fractionalloc]initWithNumerator:2denominator:5];. Fraction*frac3=[fraclmul:frac2];//printit[fraclprint];. printf(Hn);.[frac2print];printf("=");89. [frac3print];printf(”ヽn");//freememory.[fraclrelease];[frac2release];[frac3release];return0;}output1.1/3*2/5=2/15重點是@implementation跟@interface這兩行:?interfaceFraction(Math)以及@implementationFraction(Math).(同一個class)只能有一個同名的category?其他的categories得加上不同的、獨ー無二的名字。Categories在建立privatemethods時十分有用。因為Objective-C并沒有像Java這種private/protected/publicmethods的概念,所以必須要使用categories來達成這種功能。作法是把privatemethod從你的classheader(.h)檔案移到implementation(.m)檔案。以下是此種作法ー個簡短的範例。MyClass.h.#import..@interfaceMyClass:NSObject.-(void)publicMethod;..@endMyClass.m#import"MyClass?h”.#import. @implementationMyClass-(void)publicMethod{printf("publicmethod\n");.).@end//privatemethods@interfaceMyClass(Private)-(void)privateMethod;@end.. @implementationMyClass (Private)-(void) privateMethod{printf( "privatemethod\n");}@end.main.m#import"MyClass.h"9. intmain(intargc,constchar*argv[]){MyClass*obj=[[MyClassalloc]init];//thiscompiles.. [objpublicMethod];. //thisthrowserrorswhencompiling. //[objprivateMethod];//freememory[objrelease];return0;)output..PosingPosing有點像categories,但是不太ー樣。它允許你擴充一?個class,并且全面性地的扮演(pose)這個superclass。例如:你有一個擴充NSArray的NSArrayChiId物件。如果你讓NSArrayChild扮演NSArray,則在你的程式碼中所有的NSArray都會自動被替代為NSArrayChild。FractionB.h..#import“Fraction?h”..@interfaceFractionB:Fraction,-(void)print;.@endFractionB.m#import"FractionB.h".#import@implementationFractionB-(void)print{printf("(%i/%i)"znumeratorrdenominator);}@endmain.m#import#import"Fraction.h"

33343536373839404142434445464748495051525354555657585960616263646566676869#importMFractionB.hHintmain(intargc,constchar*argv[]){Fraction*frac=[[Fractionalloc]initWithNumerator:3denominator:10];//printitprintf("Thefractionis:”);[fracprint];printf("\n");//makeFractionBposeasFraction[FractionBposeAsClass:[Fractionclass]];Fraction*frac2=[[Fractionalloc]initWithNumerator:3denominator:10];//printitprintf("Thefractionis:");[frac2print];printf("\n");//freememory[fracrelease];[frac2release];return0;}outputfractionis:3/10

2.3.Thefractionis:(3/10)這個程式的輸出中,第一個fraction會輸出3/10,而第二個會輸出(3/10)〇這是FractionB中實作的方式。poseAsClass這個method是NSObject的一部份,它允許subclass扮演superclassoProtocolsObjective-C裡的Protocol與Java的interface或是C++的purelyvirtualclass相同。Printing.h^protocolPrinting-(void)print;@endFraction.h#import#import"Printing"@interfaceFraction:NSObject{intnumerator;intdenominator;)-(Fraction*)initWithNumerator:(int)ndenominator:(int)d;-(void)setNumerator:(int)d;-(void)setDenominator:(int)d;-(void)setNumerator:(int)nandDenominator:(int)d;-(int)numerator;-(int)denominator;@endFraction.m#import"Fraction."#import@implementationFraction-(Fraction*)initWithNumerator:(int)ndenominator:(int)d{246.self=[superinit];if(self){[selfsetNumerator:nandDenominator:d];)returnself;}-(void)print{260.printf("%i/%i",numerator,denominator);}264.-(void)setNumerator:(int)n{nnumerator=n;)-(void)setDenominator:(int)d{ddenominator=d;}276.-(void)setNumerator:(int)nandDenominator:(int)d{nnumerator=n;ddenominator=d;)-(int)denominator{returndenominator;)290.-(int)numerator{returnnumerator;)-(Fraction*)copyWithZone:(NSZone*)zone{return[[FractionallocWithZone:zone]initWithNumerator:numeratordenominator:denominator];)@endComplex.h#import#importHPrinting.hn@interfaceComplex:NSObject{doublereal;doubleimaginary;)-(Complex*)initWithReal:(double)randlmaginary:(double)i;-(void)setReal:(double)r;"(void)setImaginary:(double)i;325."(void)setReal:(double)randlmaginary:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論