ObjC学习6-分类、协议及预处理程序

来源:互联网 发布:stc单片机论文 编辑:程序博客网 时间:2024/04/29 18:44

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#抽象类,预处理程序就是宏= =。

原创粉丝点击