ObjC學習6-分類、協議及預處理程序

1.分類 分類就是以模塊的方式向類添加方法 

如下 用Class(BB)分類 爲ClassB類添加了printB printC的方法


@interface ClassB:NSObject
{
}
-(void) print;


@end
@implementation ClassB


-(void) print
{
    NSLog(@"i am b!");
}
@end


@interface ClassB(BB)
-(void) printB;
-(void) printC;
@end


@implementation ClassB(BB)

-(void) printB
{
     NSLog(@"i am b printB!");
}
-(void) printC
{
  NSLog(@"i am b printC!");
}

@end


結果:


B就擴展了printB printC的方法~


2.協議 協議就是多個類共享一個方法列表

@protocol 定義協議 @optional 定義可選方法 @required指出需要列出的方法

這裏定義一個Drawing的協議

@protocol Drawing
-(void) print1;
-(void) erase;
@end


用Class去實現它



@interface ClassA:NSObject<Drawing> //如果有多個在尖括號裏面用逗號隔開
{
}
-(void) print;


@end

@implementation ClassA

-(void) print
{
    NSLog(@"i am a!");
}

-(void) print1
{
     NSLog(@"i am p1!");
}
-(void) erase
{
     NSLog(@"i am erase!");
}
@end


主程序調用print1 及erase方法,結果:


可以用 conformsToProtocol來查看該對象是否遵循Drawing協議~

    if([aa conformsToProtocol:@protocol(Drawing) ]==YES)
    {
        NSLog(@"aa is protocol yes");
    }else{
         NSLog(@"aa is not protocol yes");
    }
    if([bb conformsToProtocol:@protocol(Drawing) ]==YES)
    {
        NSLog(@"bb is protocol yes");
    }else{
         NSLog(@"bb is not protocol yes");
    }

結果:

*和類名一樣,協議名也必須是唯一的。

協議也可以擴展協議,如:

@protocol Drawing3d<Drawing>

分類也可以採用協議,如:

@interface Fraction(haha) <Drawing>


3.非正式協議

非正式(informal)協議它實際上時一個分類,列出了一組方法卻並沒有實現他們。

@interface NSObnject(NS...)

-(bool)....

@end

在@protocol 也可以使用@optional來定義可以不實現的方法 -類似非正式協議 


4.合併對象

之前的square類可以寫成

...square :NSObjeect 

{Rectangle*rec}

...

繼承Obj而不繼承Rectangle 這樣就把對象包含進來~也是類擴展的另外一種形式


5.預處理語句

預處理語句就是在分析OC程序先處理這些語句

 #define PI 3.14 

這樣就定義了一個PI的常量 沒有= 沒有; 太神奇了。。。

 NSLog(@"%f",12*PI);

   結果:

2013-05-22 01:40:00.832 Test[3265:c07] 37.680000

更高級的定義

#define TWO_PI 2.0*3.14

#define AND &&

#define OR ||

    if(1 OR 0)

    {

        ....

    }


不止可以定義變量 還可以定義表達式 符號 等等任何東西。。

#define IS_LEAP_YEAR year%4==0&&year%100!=0||year%400==0

if(IS_LEAP_YEAR)

{...}



#define SQUARE(X) X*X //平方
#define MAX(a,b) (((a)>(b))?(a):(b)) //大小
#define IS_LOWER_CASE(x) (((x)>='a')&&((x)<='z')) //是否是小寫字符
#define TO_UPPER(x) (IS_LOWER_CASE(x)?(x)-'a'+'A':(x)) //轉換爲大寫


//#運算符 可以再宏定義參數前放一個#
#define str(x) # x
#define printint(var) printf(# var "=%i\n",var )


//##運算符 把兩個標記連接到一起 token
#define printx(n) printint(10 ## n)


主程序調用:

    NSLog(@"%i",SQUARE(2));//平方
    NSLog(@"%i",MAX(1,3));//比較大小
    NSLog(@"%c",TO_UPPER('a'));//轉換爲大寫


    int count1 =100;
    printint(count1);//調用帶#的宏


    printx(10);//調用帶##的宏

結果:



我們可以把宏抽離出來放入一個hong.h的頭文件

然後用#import "hong.h"指令包含在程序中,這樣可以把定義集中起來~

類似.NET WEB開發中的用戶控件的道理。。。


6.條件編譯 開關程序的各種語句

    //條件編譯 對調試非常有用
    #ifdef DEBUG
    NSLog(@"def debug");
    #else
     NSLog(@"ndef debug");
    #endif // DEBUG
    NSLog(@"--");


    #if !defined (DEBUG)
    NSLog(@"ndef debug");
    #else
    NSLog(@"else");
    #endif // DEBUG


    #if defined(DEBUG)&& DEBUG //定義了DEBUG 並且DEBUG非零才執行
    NSLog(@"yes~");//不會顯示的~~
    #endif // defined



    //一些情況下需要定義一些已經定義的名稱爲未定義 需要用到#undef
    //#undef name
    //那麼#ifdef name 爲假



總結:

分類是擴展某類的方法列表,協議類似C#抽象類,預處理程序就是宏= =。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章