OC學習篇之—寫類別(類的擴展)


首先我們來看一下場景,如果我們現在想對一個類進行功能的擴充,我們該怎么做?

 

對於面向對象編程的話,首先會想到繼承,但是繼承有兩個問題:

第一個問題:繼承的前提是這個類可以被繼承,因為在Java中有些類是不允許繼承的,定義成final類,同樣的OC中也是有不可以繼承的類

第二個問題:這個類可以被繼承,但是繼承我們知道是侵入性的,就是我可能只是想實現一個功能,但是繼承之后,子類就會把父類的所有功能(屬性和方法)都繼承了,這個代價太大了。沒必要

 

所以對於Java中,我們可以使用聚合的方式去實現,

而對於C++的話,直接在定義一個功能類,然后讓這個目標類繼承功能類,因為C++中是可以多繼承的

Java和OC是單繼承的,不允許多繼承

 

那么在OC中當然我們也可以像Java那種方式去采用聚合處理,但是OC中還有一個更強大的處理方式,那就是類別了,下面來看一下例子:我們現在想給NSString類提供一個校驗郵箱的方法validateEmail,OC中NSString類就是不可以繼承的。

不說了,直接看代碼:

NSString+Extension.h

 

 

  1. //  
  2. //  Extension.h  
  3. //  09_ClassTarget  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. //定義類別的文件命名規則:類名+類別名稱,如“NSString+Extension.h"  
  12. @interface NSString (Extension)  
  13.   
  14. - (BOOL)validateEmail;  
  15.   
  16. //覆蓋NSString中的intValue方法  
  17. - (NSInteger)intValue;  
  18.   
  19. @end  

 

 

NSString+Extension.m

[objc]  view plain  copy
  1. //  
  2. //  Extension.m  
  3. //  09_ClassTarget  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import "NSString+Extension.h"  
  10.   
  11. @implementation NSString (Extension)  
  12.   
  13. - (BOOL)validateEmail{  
  14.     NSRange range = [self rangeOfString:@"@"];  
  15.     if(range.location == NSNotFound){  
  16.         return NO;  
  17.     }else{  
  18.         return YES;  
  19.     }  
  20. }  
  21.   
  22. //這里可以看出,這里是沒辦法調用NSString中得intValue方法,這個和繼承有區別的  
  23. - (NSInteger)intValue{  
  24.     NSLog(@"intValue");  
  25.     return 0;  
  26. }  
  27.   
  28. @end  

這里我們就定義了一個類目,下面來解釋一下:

類別文件的定義格式:

類別的文件名的格式:"需要添加類別的類名+類別的名稱"

比如這里我們需要對NSString類添加一個類目Extension,那么文件名就是:NSString+Extension.h和NSString+Extension.m

 

類目的定義格式:

 

@interface 需要添加類別的類名 (類別名)

....

@end

這個和類定義格式差不多,就是在后面多了一個括號類別名

例如:

 

@interface NSString (Extension)

....

@end

 

類別名是可以隨便取的

 

看到上面的代碼,在NSString+Extension.h中

我們就可以定義validateEmail方法了,同時我們在定義了一個intValue方法

intValue方法是NSString本身就有的,這里就是為了演示一下,如果在添加的類目中重新定義了類中的已有的方法,那么類目中的方法會被覆蓋,和類的繼承差不多,但是這里有一點需要注意,這里是不能使用super關鍵字去調用NSString的intValue方法的,所以intValue覆蓋了NSString類中的intValue方法之后,NSString類中的intValue方法原先的功能就沒有了,這個得注意一下。

 

看一下測試代碼

main.m

 

[objc]  view plain  copy
  1. //  
  2. //  main.m  
  3. //  09_ClassTarget  
  4. //  
  5. //  Created by jiangwei on 14-10-11.  
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10.   
  11. #import "NSString+Extension.h"  
  12.   
  13. //這里只是為了演示如果想擴展一個類的功能,可以通過繼承的方式去實現  
  14. //但是通過繼承來實現這項功能話,有點大材小用的感覺,因為我們只需要一個判斷郵箱的合法性的方法,所以繼承就大了,沒必要  
  15. //但是這里會出錯,因為NSString是不允許繼承的  
  16.   
  17. //所以這里我們就要用到一個很強大的技術:類目  
  18. //類目的定義和累的定義相似,在.h文件里聲明,.m文件中實現方法  
  19.   
  20. //類目可以覆蓋方法,但是不會再執行之前的那個方法了,而是調用新的方法  
  21. //類目不能為類添加屬性(實例變量)  
  22.   
  23. int main(int argc, const charchar * argv[]) {  
  24.     @autoreleasepool {  
  25.           
  26.         NSString *s = @"123456@qq.com";  
  27.         BOOL isEmail = [s validateEmail];  
  28.         if(isEmail){  
  29.             NSLog(@"有效郵箱");  
  30.         }else{  
  31.             NSLog(@"無效郵箱");  
  32.         }  
  33.           
  34.         //調用的是我們類目中的intValue方法  
  35.         NSInteger i = [s intValue];  
  36.         NSLog(@"intValue is %i",i);  
  37.     }  
  38.     return 0;  
  39. }  

這樣我們就給NSString類添加了一個校驗郵箱的方法,同時類目中的intValue方法也會覆蓋原先類中的intValue方法。

 

 

通過這個例子,我們可以看到OC中的類目真的很強大呀!!

而且類目其實還有一個隱藏的用處,從他的字面意思上就知道具有分類的作用,比如一個類中的方法有時候我們可能會需要進行分類(比如:打印分類,比較分類等),這樣代碼看上去也很優雅。我們可以翻看Foundation框架中的NSArray類(這個類我們后面會說到的,和Java中的List差不多):

還有一個類目。

這里我們也了解到了,一個類是可以定義多個類目的。而且類目的作用可以沿襲到子類,就是父類的類目中的方法子類依然可以使用super關鍵字進行調用的。

 

總結

這一篇文章就介紹了OC中的一個強大功能類目,這個在對以后的擴展性起到至關重要的作用,也算是OC中的一個重點了,后續我們會經常用到這個功能。


免責聲明!

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



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