OC和C的最大區別就是具備了面向對象的功能,那麼說到面向對象,就不得不說類這個概念了,若是學過Java的話,那麼對類和對象的概念就不陌生了,由於Java是很是純正的面向對象設計語言。關於類和對象的概念,這裏就不仔細介紹了,網上有各類解釋。咱們之間來開一下OC中如何定義一個類,如何實例化出一個對象等。java
首先咱們新建一個工程,系統會自動建立main.m文件的,這時候,咱們右鍵項目,選擇New File..web
而後選擇OS X中的Source,在選擇Cocoa Class,點擊下一步學習
點擊下一步spa
這裏填寫如下類的名稱,這個和Java中是相似的了,點擊下一步:.net
咱們能夠看到,新建了一個Person類,可是這個和Java就有點區別了,一個類是有兩部分構成的,一個是類的頭文件Person.h(通常是在該文件中作定義工做的),還有一個是Person.m文件,這個通常是實現頭文件中定義的內容。這個也是延續了C語言中的項目結構吧。通常頭文件只負責定義功能,.c文件負責實現具體功能的。這裏也是相似吧。設計
下面來看一下Person.h頭文件中類的定義格式:指針
// Person.h // 02_ClassDemo // // Created by jiangwei on 14-10-10. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import <Foundation/Foundation.h> @interface Person : NSObject{ //在{}中定義屬性(全局變量/實例變量) //注意:只能定義不能賦值,由於這裏只是在作聲明操做,不能賦值的 //加上下劃線,爲了區分局部變量 NSString *_name;//姓名,默認值是nil:空指針,能夠查看定義:#define nil NULL NSInteger _age;//年齡,默認值是0 } //定義方法 //-:實例方法,+:類方法 //格式:方法說明 (返回類型) 方法名 : (參數類型)參數名稱 //注意方法名是shopping:,不是shopping,這個要注意 - (void)shopping:(float)price; //定義方法設置屬性值(注意setXXX) - (void)setName:(NSString *)name; - (void)setAge:(NSInteger)age; //定義方法的獲取屬性值(注意不是getXXX,而是直接的屬性名,由於getXXX在OC中還有其餘用途) - (NSString *)name; - (NSInteger)age; //多個參數的方法定義 //方法名兩部分組成的:setName: setAge: - (void)setName:(NSString *)name setAge:(NSInteger)age; //或者方法名:setName: :,後面的能夠省略,可是這種方式不建議使用 //- (void)setName:(NSString *)name :(NSInteger)age; //類方法 //在這個方法中是沒法訪問屬性的,由於屬性是屬於對象的,不是類的 + (Person *)newPerson; @end首先看到類的定義的關鍵字是:
@interfacecode
通常類的定義格式爲:orm
@interface 類名:NSObject{對象
定義屬性
}
定義方法
一、OC中任何一個類都是繼承NSObject,這個和Java中的Object是一個概念的,因此這裏須要導入
#import <Foundation/Foundation.h>
其實Java中的Object對象是在java.lang.*包中的,不過Java並不會導入這個包,由於Object類的類加載器決定的,不須要導入的.
二、這裏的繼承符號和C++中是同樣的,使用冒號:
三、在{}類定義類的屬性,關於這裏所說的屬性和Java中的屬性不是一個概念了,OC中只要定義在{}中的字段就是類的屬性,而Java中是有getXXX/setXXX的方法,才叫屬性。同時也得注意,OC中類中定義的屬性名是如下劃線:"_"開頭,爲何要這樣作,就是爲了區分後面的局部變量與其重名了,固然咱們在Java中通常是以m開頭,或者其餘方式,Java中沒有那麼強的規範,可是OC中仍是強烈建議用這種方式的,還有一點要注意,在定義設置方法的時候,通常樣式是setXXX,可是在定義取值的方法的時候直接是XXX,而不是getXXX了,這個也是和Java有區別的,至於爲何這麼作,由於get開頭的方法已經有其餘用處了,後面會說到。這裏就注意一下就能夠了。
四、在屬性定義的後面就是簡單的定義方法了
下面在來看一下如何定義方法:
OC中定義方法和Java語言有很大的不一樣,因此這裏很難記住,若是不經常使用的話,看一下方法的定義格式:
方法說明 (返回類型) 方法名 : (參數類型)參數名稱
一種是減號:"-",表示該方法是對象方法,就是必須用對象實例才能調用的
一種是加號:"+",表示該方法是類方法,就是能夠用類直接調用的,不須要實例化對象的,相似於Java中的static方法
二、返回類型:這個就簡單了,和Java語言很相似了
三、方法名:方法名和Java中就不太同樣了,看個例子:
//注意方法名是shopping:,不是shopping,這個要注意 - (void)shopping:(float)price;
這個方法的方法名是
shopping: 是包含冒號的,再看個例子:
//多個參數的方法定義 //方法名兩部分組成的:setName: setAge: - (void)setName:(NSString *)name setAge:(NSInteger)age;多參數的方法定義,那麼這個方法的方法名就是 setName:setAge:
四、(參數類型)參數名稱:這個和Java也是有很大的區別的,感受像是和Java中定義的相反了,他用括號把類型括起來了。OC中的對象類型和Java中的使用不同,OC中的對象類型至關於C中指針定義樣式(類名 *),這點須要注意。
固然在類定義的結束地方使用@end關鍵字的
看完了類的定義,下面在來看一下類的具體實現了:
Person.m
// // Person.m // 02_ClassDemo // // Created by jiangwei on 14-10-10. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import "Person.h" @implementation Person //實現方法 - (void) shopping : (float)price{ NSLog(@"%@ shopping %f",_name,price); } - (void)setName:(NSString *)name{ _name = name; } - (void)setAge:(NSInteger)age{ _age = age; } - (NSString *)name{ return _name; } - (NSInteger)age{ return _age; } - (void)setName:(NSString *)name setAge:(NSInteger)age{ _name = name; _age = age; } + (Person *)newPerson{ return [[Person alloc] init]; } @end看到類的實現使用的是 @implementation 關鍵字
在實現的源文件中,必須導入類的定義的頭文件
#import "Person.h"
這樣的一種形式,和C語言中的工程結構很是類似。而後就是對頭文件中定義的一些方法的具體實現了,並且在實現文件中,咱們能夠訪問類中定義的屬性。其餘的就沒有什麼難度了,就不在細說了,一樣的類的結束標誌:@end
類定義和實現都介紹完了,下面來看一下如何使用吧:
main.m
// // main.m // 02_ClassDemo // // Created by jiangwei on 14-10-10. // Copyright (c) 2014年 jiangwei. All rights reserved. // //類的定義放在.h文件中 //類的實現放在.m文件中 //定義一個類的步驟 //定義類名、編寫類的屬性、編寫類的行爲 #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { //建立對象 //在內存中申請一塊內存區域 //Person *person = [Person alloc]; //調用初始化方法,初始化一些默認數據 //可能上面申請的內存以前有被使用過,還會有之前的數據。因此咱們須要將其數據清空,這時候就會將默認值進行賦值(至關於清空操做) //person = [person init]; //合併 //這裏申請了兩塊內存:一個是對象指針變量,一個是alloc申請的 //能夠看出alloc/init方法是類方法、能夠查看NSObject對象的定義 Person *person = [[Person alloc] init]; //還有另外的一種方式建立一個對象,可是這種方式不建議使用,由於這種方式至關於把上面的兩個合併 //有時候咱們須要將上面的兩個步驟進行分開操做的 //Person *person1 = [Person new]; //設置名字 [person setName:@"jaingwei"]; //調用實例方法shopping [person shopping:200]; Person *person1 = [[Person alloc] init]; [person1 setName:@"huangdaoyang"]; [person1 shopping:300]; //同時設置兩個屬性的值,可是這種方式不建議使用,建議使用set方法 [person1 setName:@"huangdaoyang" setAge:22]; //get方法調用 NSString *person_name = [person name]; NSLog(@"name is %@",person_name); NSString *person1_name = [person1 name]; NSLog(@"name is %@",person1_name); //類方法調用 Person *person2 = [Person newPerson]; [person2 setName:@"shixin" setAge:22]; [person2 shopping:400]; //空指針 Person *person3 = nil; //不執行任何操做,可是也不會報錯空指針異常 [person3 setName:@"空對象" setAge:22]; } return 0; }OC中實例化一個對象的方式是:
Person *person = [[Person alloc] init];
首先是指針類型的樣式定義一個變量,而後是調用類的alloc方法,接着調用init方法,這裏有點比較奇怪,咱們在定義Person類的時候,沒有定義alloc和init方法,這裏爲何不報錯呢?這個就和Java很類似了,由於OC中任何類都是集成NSObject類的,那麼天然想到了這兩個方法是NSObject定義的。並且咱們能夠看到alloc方法是類方法,init是對象方法
同時,OC中的方法調用方式:
對象方法:[對象變量 方法名 參數]
類方法:[類名 方法名 參數]
這裏實例化一個對象和Java中有很大的區別的,Java中直接new一個就能夠了。這裏須要調用兩個方法alloc和init
能夠這麼理解吧:alloc至關於給這個對象分配內存空間,init是調用這個類的構造方法,對屬性和字段進行初始化操做
固然上面的實例化操做也能夠變成兩步:
Person *person = [Person alloc]; //調用初始化方法,初始化一些默認數據 //可能上面申請的內存以前有被使用過,還會有之前的數據。因此咱們須要將其數據清空,這時候就會將默認值進行賦值(至關於清空操做) person = [person init];可是OC中建議的方式仍是上面那種。
對象方法的調用,設置名字:
//設置名字 [person setName:@"jaingwei"];
多個參數的對象方法調用,同時設置名字和年齡
//同時設置兩個屬性的值,可是這種方式不建議使用,建議使用set方法 [person1 setName:@"huangdaoyang" setAge:22];
//類方法調用 Person *person2 = [Person newPerson];
總結
好了,關於OC中類的定義以及實現,如何使用就介紹到這裏了,咱們在學習的過程當中能夠和一門面向對象語言相比較學習,這樣可能會學習的快點。