OC學習篇之---類的定義


 OC中類的相關知識 

 

OC和C的最大區別就是具有了面向對象的功能,那么說到面向對象,就不得不說類這個概念了,如果學過Java的話,那么對類和對象的概念就不陌生了,因為Java是非常純正的面向對象設計語言。關於類和對象的概念,這里就不仔細介紹了,網上有各種解釋。我們之間來開一下OC中如何定義一個類,如何實例化出一個對象等。

首先我們新建一個工程,系統會自動創建main.m文件的,這時候,我們右鍵項目,選擇New File..

然后選擇OS X中的Source,在選擇Cocoa Class,點擊下一步

點擊下一步

這里填寫以下類的名稱,這個和Java中是類似的了,點擊下一步:

我們可以看到,新建了一個Person類,但是這個和Java就有點區別了,一個類是有兩部分構成的,一個是類的頭文件Person.h(一般是在該文件中做定義工作的),還有一個是Person.m文件,這個一般是實現頭文件中定義的內容。這個也是延續了C語言中的項目結構吧。一般頭文件只負責定義功能,.c文件負責實現具體功能的。這里也是類似吧。

下面來看一下Person.h頭文件中類的定義格式:

 

[objc]  view plain  copy
  1. //  Person.h  
  2. //  02_ClassDemo  
  3. //  
  4. //  Created by jiangwei on 14-10-10.  
  5. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  6. //  
  7.   
  8. #import <Foundation/Foundation.h>  
  9.   
  10. @interface Person : NSObject{  
  11.     //在{}中定義屬性(全局變量/實例變量)  
  12.     //注意:只能定義不能賦值,因為這里只是在做聲明操作,不能賦值的  
  13.     //加上下划線,為了區分局部變量  
  14.     NSString *_name;//姓名,默認值是nil:空指針,可以查看定義:#define nil NULL  
  15.     NSInteger _age;//年齡,默認值是0  
  16. }  
  17.   
  18. //定義方法  
  19. //-:實例方法,+:類方法  
  20. //格式:方法說明 (返回類型) 方法名 : (參數類型)參數名稱  
  21. //注意方法名是shopping:,不是shopping,這個要注意  
  22. - (void)shopping:(float)price;  
  23.   
  24. //定義方法設置屬性值(注意setXXX)  
  25. - (void)setName:(NSString *)name;  
  26. - (void)setAge:(NSInteger)age;  
  27.   
  28. //定義方法的獲取屬性值(注意不是getXXX,而是直接的屬性名,因為getXXX在OC中還有其他用途)  
  29. - (NSString *)name;  
  30. - (NSInteger)age;  
  31.   
  32. //多個參數的方法定義  
  33. //方法名兩部分組成的:setName: setAge:  
  34. - (void)setName:(NSString *)name setAge:(NSInteger)age;  
  35. //或者方法名:setName: :,后面的可以省略,但是這種方式不建議使用  
  36. //- (void)setName:(NSString *)name :(NSInteger)age;  
  37.   
  38. //類方法  
  39. //在這個方法中是無法訪問屬性的,因為屬性是屬於對象的,不是類的  
  40. + (Person *)newPerson;  
  41. @end  

首先看到類的定義的關鍵字是:

 

@interface

 

一般類的定義格式為:

@interface 類名:NSObject{

定義屬性

}

定義方法

 

這里有幾點需要說明:

1、OC中任何一個類都是繼承NSObject,這個和Java中的Object是一個概念的,所以這里需要導入

#import <Foundation/Foundation.h>

其實Java中的Object對象是在java.lang.*包中的,不過Java並不會導入這個包,因為Object類的類加載器決定的,不需要導入的.

2、這里的繼承符號和C++中是一樣的,使用冒號:

3、在{}類定義類的屬性,關於這里所說的屬性和Java中的屬性不是一個概念了,OC中只要定義在{}中的字段就是類的屬性,而Java中是有getXXX/setXXX的方法,才叫屬性。同時也得注意,OC中類中定義的屬性名是以下划線:"_"開頭,為什么要這樣做,就是為了區分后面的局部變量與其重名了,當然我們在Java中一般是以m開頭,或者其他方式,Java中沒有那么強的規范,但是OC中還是強烈建議用這種方式的,還有一點要注意,在定義設置方法的時候,一般樣式是setXXX,但是在定義取值的方法的時候直接是XXX,而不是getXXX了,這個也是和Java有區別的,至於為什么這么做,因為get開頭的方法已經有其他用處了,后面會說到。這里就注意一下就可以了。

4、在屬性定義的后面就是簡單的定義方法了

 

下面在來看一下如何定義方法:

OC中定義方法和Java語言有很大的不同,所以這里很難記住,如果不常用的話,看一下方法的定義格式:

 

方法說明 (返回類型) 方法名 : (參數類型)參數名稱

 

1、方法說明有兩種:

一種是減號:"-",表示該方法是對象方法,就是必須用對象實例才能調用的

一種是加號:"+",表示該方法是類方法,就是可以用類直接調用的,不需要實例化對象的,類似於Java中的static方法

2、返回類型:這個就簡單了,和Java語言很類似了

3、方法名:方法名和Java中就不太一樣了,看個例子:

[objc]  view plain  copy
  1. //注意方法名是shopping:,不是shopping,這個要注意  
  2. - (void)shopping:(float)price;  

 

這個方法的方法名是

shopping: 是包含冒號的,再看個例子:

 

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1.   

 

[objc]  view plain  copy
  1. //多個參數的方法定義  
  2. //方法名兩部分組成的:setName: setAge:  
  3. - (void)setName:(NSString *)name setAge:(NSInteger)age;  

多參數的方法定義,那么這個方法的方法名就是setName:setAge:

 

4、(參數類型)參數名稱:這個和Java也是有很大的區別的,感覺像是和Java中定義的相反了,他用括號把類型括起來了。OC中的對象類型和Java中的使用不一樣,OC中的對象類型相當於C中指針定義樣式(類名 *),這點需要注意。

 

當然在類定義的結束地方使用@end關鍵字的

 

看完了類的定義,下面在來看一下類的具體實現了:

Person.m

 

[objc]  view plain  copy
  1. //  
  2. //  Person.m  
  3. //  02_ClassDemo  
  4. //  
  5. //  Created by jiangwei on 14-10-10.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import "Person.h"  
  10.   
  11. @implementation Person  
  12.   
  13. //實現方法  
  14. - (void) shopping : (float)price{  
  15.     NSLog(@"%@ shopping %f",_name,price);  
  16. }  
  17.   
  18. - (void)setName:(NSString *)name{  
  19.     _name = name;  
  20. }  
  21. - (void)setAge:(NSInteger)age{  
  22.     _age = age;  
  23. }  
  24. - (NSString *)name{  
  25.     return _name;  
  26. }  
  27. - (NSInteger)age{  
  28.     return _age;  
  29. }  
  30. - (void)setName:(NSString *)name setAge:(NSInteger)age{  
  31.     _name = name;  
  32.     _age = age;  
  33. }  
  34. + (Person *)newPerson{  
  35.     return [[Person alloc] init];  
  36. }  
  37.   
  38. @end  

看到類的實現使用的是@implementation 關鍵字

 

在實現的源文件中,必須導入類的定義的頭文件

#import "Person.h"

這樣的一種形式,和C語言中的工程結構非常相似。

然后就是對頭文件中定義的一些方法的具體實現了,而且在實現文件中,我們可以訪問類中定義的屬性。其他的就沒有什么難度了,就不在細說了,同樣的類的結束標志:@end

類定義和實現都介紹完了,下面來看一下如何使用吧:

main.m

 

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1. //  
  2. //  main.m  
  3. //  02_ClassDemo  
  4. //  
  5. //  Created by jiangwei on 14-10-10.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. //類的定義放在.h文件中  
  10. //類的實現放在.m文件中  
  11.   
  12. //定義一個類的步驟  
  13. //定義類名、編寫類的屬性、編寫類的行為  
  14.   
  15. #import <Foundation/Foundation.h>  
  16.   
  17. #import "Person.h"  
  18.   
  19. int main(int argc, const charchar * argv[]) {  
  20.     @autoreleasepool {  
  21.         //創建對象  
  22.         //在內存中申請一塊內存區域  
  23.         //Person *person = [Person alloc];  
  24.         //調用初始化方法,初始化一些默認數據  
  25.         //可能上面申請的內存之前有被使用過,還會有以前的數據。所以我們需要將其數據清空,這時候就會將默認值進行賦值(相當於清空操作)  
  26.         //person = [person init];  
  27.           
  28.         //合並  
  29.         //這里申請了兩塊內存:一個是對象指針變量,一個是alloc申請的  
  30.         //可以看出alloc/init方法是類方法、可以查看NSObject對象的定義  
  31.         Person *person = [[Person alloc] init];  
  32.           
  33.         //還有另外的一種方式創建一個對象,但是這種方式不建議使用,因為這種方式相當於把上面的兩個合並  
  34.         //有時候我們需要將上面的兩個步驟進行分開操作的  
  35.         //Person *person1 = [Person new];  
  36.           
  37.         //設置名字  
  38.         [person setName:@"jaingwei"];  
  39.           
  40.         //調用實例方法shopping  
  41.         [person shopping:200];  
  42.           
  43.         Person *person1 = [[Person alloc] init];  
  44.         [person1 setName:@"huangdaoyang"];  
  45.         [person1 shopping:300];  
  46.         //同時設置兩個屬性的值,但是這種方式不建議使用,建議使用set方法  
  47.         [person1 setName:@"huangdaoyang" setAge:22];  
  48.           
  49.         //get方法調用  
  50.         NSString *person_name = [person name];  
  51.         NSLog(@"name is %@",person_name);  
  52.         NSString *person1_name = [person1 name];  
  53.         NSLog(@"name is %@",person1_name);  
  54.           
  55.         //類方法調用  
  56.         Person *person2 = [Person newPerson];  
  57.         [person2 setName:@"shixin" setAge:22];  
  58.         [person2 shopping:400];  
  59.           
  60.         //空指針  
  61.         Person *person3 = nil;  
  62.         //不執行任何操作,但是也不會報錯空指針異常  
  63.         [person3 setName:@"空對象" setAge:22];  
  64.           
  65.           
  66.     }  
  67.     return 0;  
  68. }  

OC中實例化一個對象的方式是:

 

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1. Person *person = [[Person alloc] init];  

首先是指針類型的樣式定義一個變量,然后是調用類的alloc方法,接着調用init方法,這里有點比較奇怪,我們在定義Person類的時候,沒有定義alloc和init方法,這里為什么不報錯呢?這個就和Java很相似了,因為OC中任何類都是集成NSObject類的,那么自然想到了這兩個方法是NSObject定義的。而且我們可以看到alloc方法是類方法,init是對象方法

同時,OC中的方法調用方式:

對象方法:[對象變量  方法名 參數]

類方法:[類名  方法名 參數]

這里實例化一個對象和Java中有很大的區別的,Java中直接new一個就可以了。這里需要調用兩個方法alloc和init

可以這么理解吧:alloc相當於給這個對象分配內存空間,init是調用這個類的構造方法,對屬性和字段進行初始化操作

當然上面的實例化操作也可以變成兩步:

 

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1. Person *person = [Person alloc];  
  2. //調用初始化方法,初始化一些默認數據  
  3. //可能上面申請的內存之前有被使用過,還會有以前的數據。所以我們需要將其數據清空,這時候就會將默認值進行賦值(相當於清空操作)  
  4. person = [person init];  

但是OC中建議的方式還是上面那種。

對象方法的調用,設置名字:

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1. //設置名字  
  2. [person setName:@"jaingwei"];  

 

多個參數的對象方法調用,同時設置名字和年齡

 

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1. //同時設置兩個屬性的值,但是這種方式不建議使用,建議使用set方法  
  2. [person1 setName:@"huangdaoyang" setAge:22];  


類方法的調用:

[objc]  view plain  copy
 在CODE上查看代碼片派生到我的代碼片
  1. //類方法調用  
  2. Person *person2 = [Person newPerson];  

 

總結

好了,關於OC中類的定義以及實現,如何使用就介紹到這里了,我們在學習的過程中可以和一門面向對象語言相比較學習,這樣可能會學習的快點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM