上一篇文章介紹了OC中的@class關鍵字的使用http://blog.csdn.net/jiangwei0910410003/article/details/41774747,這一篇咱們介紹一下,OC中的一個特有的亮點:類目編程
首先咱們來看一下場景,若是咱們如今想對一個類進行功能的擴充,咱們該怎麼作?框架
對於面向對象編程的話,首先會想到繼承,可是繼承有兩個問題:測試
第一個問題:繼承的前提是這個類能夠被繼承,由於在Java中有些類是不容許繼承的,定義成final類,一樣的OC中也是有不能夠繼承的類spa
第二個問題:這個類能夠被繼承,可是繼承咱們知道是侵入性的,就是我可能只是想實現一個功能,可是繼承以後,子類就會把父類的全部功能(屬性和方法)都繼承了,這個代價太大了。不必.net
因此對於Java中,咱們可使用聚合的方式去實現,code
而對於C++的話,直接在定義一個功能類,而後讓這個目標類繼承功能類,由於C++中是能夠多繼承的對象
Java和OC是單繼承的,不容許多繼承blog
那麼在OC中固然咱們也能夠像Java那種方式去採用聚合處理,可是OC中還有一個更強大的處理方式,那就是類目了,下面來看一下例子:咱們如今想給NSString類提供一個校驗郵箱的方法validateEmail,OC中NSString類就是不能夠繼承的。繼承
不說了,直接看代碼:get
NSString+Extension.h
// // Extension.h // 09_ClassTarget // // Created by jiangwei on 14-10-11. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import <Foundation/Foundation.h> //定義類目的文件命名規則:類名+類目名稱,如「NSString+Extension.h" @interface NSString (Extension) - (BOOL)validateEmail; //覆蓋NSString中的intValue方法 - (NSInteger)intValue; @end
NSString+Extension.m
// // Extension.m // 09_ClassTarget // // Created by jiangwei on 14-10-11. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import "NSString+Extension.h" @implementation NSString (Extension) - (BOOL)validateEmail{ NSRange range = [self rangeOfString:@"@"]; if(range.location == NSNotFound){ return NO; }else{ return YES; } } //這裏能夠看出,這裏是沒辦法調用NSString中得intValue方法,這個和繼承有區別的 - (NSInteger)intValue{ NSLog(@"intValue"); return 0; } @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
// // main.m // 09_ClassTarget // // Created by jiangwei on 14-10-11. // Copyright (c) 2014年 jiangwei. All rights reserved. // #import <Foundation/Foundation.h> #import "NSString+Extension.h" //這裏只是爲了演示若是想擴展一個類的功能,能夠經過繼承的方式去實現 //可是經過繼承來實現這項功能話,有點大材小用的感受,由於咱們只須要一個判斷郵箱的合法性的方法,因此繼承就大了,不必 //可是這裏會出錯,由於NSString是不容許繼承的 //因此這裏咱們就要用到一個很強大的技術:類目 //類目的定義和累的定義類似,在.h文件裏聲明,.m文件中實現方法 //類目能夠覆蓋方法,可是不會再執行以前的那個方法了,而是調用新的方法 //類目不能爲類添加屬性(實例變量) int main(int argc, const char * argv[]) { @autoreleasepool { NSString *s = @"123456@qq.com"; BOOL isEmail = [s validateEmail]; if(isEmail){ NSLog(@"有效郵箱"); }else{ NSLog(@"無效郵箱"); } //調用的是咱們類目中的intValue方法 NSInteger i = [s intValue]; NSLog(@"intValue is %i",i); } return 0; }這樣咱們就給NSString類添加了一個校驗郵箱的方法,同時類目中的intValue方法也會覆蓋原先類中的intValue方法。
經過這個例子,咱們能夠看到OC中的類目真的很強大呀!!
並且類目其實還有一個隱藏的用處,從他的字面意思上就知道具備分類的做用,好比一個類中的方法有時候咱們可能會須要進行分類(好比:打印分類,比較分類等),這樣代碼看上去也很優雅。咱們能夠翻看Foundation框架中的NSArray類(這個類咱們後面會說到的,和Java中的List差很少):
還有一個類目。
這裏咱們也瞭解到了,一個類是能夠定義多個類目的。並且類目的做用能夠沿襲到子類,就是父類的類目中的方法子類依然可使用super關鍵字進行調用的。
總結
這一篇文章就介紹了OC中的一個強大功能類目,這個在對之後的擴展性起到相當重要的做用,也算是OC中的一個重點了,後續咱們會常常用到這個功能。