object-c的Categories

來源:互聯網
上載者:User

Categories允許使用者為某個類添加新的方法(不能添加新的資料成員),而不用繼承的方式來實現。並且,即使沒有某個類的實現源碼,仍然可以這樣做。執行個體如下:
一.  例1:在不用Fraction源碼的情況下,為Fraction添加幾個數學(math)方法。 
1. 代碼: 
    需要把之前編譯好的Fraction.o和Fraction.h放到和下面檔案的同一個目錄下,例如,這裡是FractionMath目錄。 
   //1. FractionMath.h
#import "Fraction.h"

@interface Fraction (Math)
-(Fraction*) add: (Fraction*) f;
-(Fraction*) mul: (Fraction*) f;
-(Fraction*) div: (Fraction*) f;
-(Fraction*) sub: (Fraction*) f;
@end
    //2. FractionMath.m
#import "FractionMath.h"

@implementation Fraction (Math)
-(Fraction*) add: (Fraction*) f {
    return [[Fraction alloc] initWithNumerator: numerator * [f denominator] +
                                                denominator * [f numerator]
                             denominator: denominator * [f denominator]];
}

-(Fraction*) mul: (Fraction*) f {
    return [[Fraction alloc] initWithNumerator: numerator * [f numerator]
                             denominator: denominator * [f denominator]];

}

-(Fraction*) div: (Fraction*) f {
    return [[Fraction alloc] initWithNumerator: numerator * [f denominator]
                             denominator: denominator * [f numerator]];
}

-(Fraction*) sub: (Fraction*) f {
    return [[Fraction alloc] initWithNumerator: numerator * [f denominator] -
                                                denominator * [f numerator]
                             denominator: denominator * [f denominator]];
}
@end

//3. main.m
#import <stdio.h>
#import "Fraction.h"
#import "FractionMath.h"

int main( int argc, const char *argv[] ) {
    // create a new instance
    Fraction *frac1 = [[Fraction alloc] initWithNumerator: 1 denominator: 3];
    Fraction *frac2 = [[Fraction alloc] initWithNumerator: 2 denominator: 5];
    Fraction *frac3 = [frac1 mul: frac2];

    // print it
    [frac1 print];
    printf( " * " );
    [frac2 print];
    printf( " = " );
    [frac3 print];
    printf( "\n" );

    // free memory
    [frac1 release];
    [frac2 release];
    [frac3 release];

    return 0;
}

2. 編譯運行
gcc -fconstant-string-class=NSConstantString -c main.m -I /GNUstep/System/Library/Headers
gcc -c FractionMath.m -I /GNUstep/System/Library/Headers
gcc main.o Fraction.o FractionMath.o -o main -L /GNUstep/System/Library/Libraries/ -lobjc -lgnustep-base

$ ./main.exe
1/3 * 2/5 = 2/15

3.說明:
  (1) 必須將 Fraction.o和Fraction.h放在代碼的同一個目錄下,這才能引用到,否則,在連結的時候就找不到Fraction類。 

二. 例2:      在C++(或Java)那樣,對類的方法可以用private/protected/public來限制類方法的訪問防屬性;然而,在object-c中,卻沒有這樣的規定(有的只是對成員變數的限制),  現在,可以用 categories 來實現這樣的功能。執行個體如下:

    1. 代碼:
    //1.  ClassA.h
#import <Foundation/NSObject.h>

@interface ClassA: NSObject 

-(void) print;
@end 

//2. ClassA.m
#import "ClassA.h"

@implementation ClassA

//在.h中有聲明,這是個public方法
-(void) print {
    printf( "this is a public method\n");
}
@end

// private 方法
@interface MyClass (Private)
-(void) privateMethod;
@end

@implementation MyClass (Private)
-(void) privateMethod {
    printf( "this is a private method\n" );
}
@end

//3. main.m
#import <stdio.h>
#import "ClassA.h"

int main( int argc, const char *argv[] ) {
    // create a new instance
    ClassA *a = [[ClassA alloc] init];

    [a print];
    printf( "\n" );
    
    //下面這個函數會編譯出錯,因為這個函數是在.m中聲明的,不能被外部存取,這就間接實現了private功能。
    //[a privateMethod];
    return 0;
}

二. 編譯運行(略) 
三. 說明:

    (1) 在.h中聲明的print函數可以認為是public的; 
    (2) 在.m中用 "@interface MyClass (Private)"方式聲明的,不能被外部存取,所以,間接的實現了private功能。
    (3) 當然,可以把"private"改為其它的單詞,例如"aaaaaaa",都是可以的;

    (4) 對比例一,關鍵的區別是這個聲明是在.h中聲明的,還是在.m中聲明的,如果是前者,那麼,在外部就可以訪問,本來的目就是為類擴充函數,正如例1一樣;  如果在.m中聲明,那麼,外部就訪問不到了。

    (5) 從另一個角度理解,在訪問一個類的時候,需要import .h標頭檔的,如果在.h檔案中沒有相應函數的聲明,那麼,就會出現編譯錯誤了,這也很容易理解。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.