OC學習篇之---類目的概念和使用 分類: IOS 2014-12-06 14:55 2944人閱讀 評論(3) 收藏

上一篇文章介紹了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中的一個重點了,後續咱們會常常用到這個功能。

相關文章
相關標籤/搜索