首页 > 代码库 > 类目 (category),扩展(Extension)和协议(protocol) (转)

类目 (category),扩展(Extension)和协议(protocol) (转)

@类目-分类(category)

1.类目:
类目(也成类别:Category)是一种为现有类添加新方法的方式
2.类目的局限性:
1)类目无法向已有的类中添加实例变量;
2)如果类目中的方法和已有类中的方法名称冲突时,类目中的方法优先级高,发生这种情况,则已有类的原始方法永无天日,最好的办法是将自己扩展的方法和原始方法区分开来。
3.类目的作用:
?       将类的实现分散到多个不同的文件中
–      将多个类目的声明放入同一个.h文件中
–      将实现放入多个.m方法中
?       使用类目创建对私有方法的前向引用
–      就是为类创建私有方法
?       向对象添加非正式协议
–      现在逐渐被正式协议做替代

4.代码示例:

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #import <Foundation/Foundation.h>    
  2.     
  3. @interface MyClass : NSObject    
  4. {    
  5.     int var1;    
  6.     int var2;    
  7.     int var3;    
  8. }    
  9. @end    
  10. @interface MyClass(MyClassCategory1)    
  11. -(void) setVar1:(int) v;    
  12. -(int) var1;    
  13. @end    
  14. @interface MyClass(MyClassCategory2)    
  15. -(void) setVar2:(int) v;    
  16. -(int) var2;    
  17. @end    
  18. @interface MyClass(MyClassCategory3)    
  19. -(void) setVar3:(int) v;    
  20. -(int) var3;    
  21. @end    
  22.     
  23. //注意:可以将这三个类目的声明以及类的声明放到同一个.h文件中,方便导入使用    
  24.   
  25. #import “MyClass.h”    
  26. @implementation MyClass (MyCategory1)    
  27. -(void) setVar1 : (int) v    
  28. {    
  29.     var1 = v;    
  30. }    
  31. -(int) var1    
  32. {    
  33.     return var1;    
  34. }    
  35. @end    
  36. //注意:其他两个@implementation部分放入其他单独的两个.m文件中    
  37.   
  38.   
  39. #import "MyClass.h"    
  40.   
  41. @implementation MyClass    
  42. -(NSString *)description    
  43. {    
  44.     return [NSString stringWithFormat:@"%d,%d,%d",var1,var2,var3];    
  45. }    
  46. @end    
  47.   
  48. #import “MyClass.h”    
  49. int main(int argc,const charchar * argv[])    
  50. {    
  51.     @autoreleasepool{    
  52.         MyClass *mc = [[MyClass alloc]init];    
  53.         //此处mc对象可以正常调用三对儿存取方法    
  54.         //证明类目将每一部分的存取方法都已经实现    
  55.         NSLog(@”%@”,mc);    
  56.   
  57.     }    
  58. }    

 

@扩展--延展(Extension)

1.作用:
?类的延展也可以将方法变为类的私有方法
?将私有方法声明到一个匿名类目中,并且将这个匿名类目放到类的.m文件里
?然后在类的.m的@implementation部分将这个匿名类目中的私有方法进行实现
?这样的也能够写出私有方法,但是同样也可以强行在类外部调用,也会有编译器警告
?如果私有方法的声明放入一个匿名类目中,并且这个类目放入一个.h文件中
?这个.h文件可以看做私有API
?可以将私有API不公开,而只开放给许可者来调用
?然后在使用私有API时将那个.h文件导入,然后调用私有方法,编译器警告便会消失

2.代码示例:

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. @interface MyClass : NSObject    
  2. - (float)value;    
  3. @end    
  4.      
  5.      
  6. @interface MyClass () { //注意此处:扩展    
  7.     float value;    
  8. }    
  9. - (void)setValue:(float)newValue;    
  10. @end    
  11.      
  12. @implementation MyClass    
  13.      
  14. - (float)value {    
  15.     return value;    
  16. }    
  17.      
  18. - (void)setValue:(float)newValue {    
  19.     value = newValue;    
  20. }    
  21.      


@协议(protocol)

1.作用:

?前面提到了非正式协议,使用非正式协议时,只需要实现自己期望的方法即可

 

?对应的,还有一个正式协议
?正式协议也是一个方法列表,和非正式协议不同的是,采用正式协议时需要在声明类时说明要采用的协议
?协议就是一套标准
–定义了应该实现什么,但不关心具体怎么实现
?OC的协议是由@protocol声明的一组方法列表
–要求其它的类去实现,相当于@interface部分的声明
–@required标注的方法为必须实现方法
–@optional标注的方法为可以选择实现
?协议的实现又叫采用(遵守)协议

2.代码示例:

 

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. @protocol MyProtocol <NSObject>    
    2. @required    
    3. -(int) addX:(int) x andY:(int) y;    
    4. @optional    
    5. -(int) substructX:(int) x andY:(int) y;    
    6. @end    
    7.     
    8.     
    9. #import "MyProtocol.h"    
    10. @interface MyClass : NSObject <MyProtocol>    
    11. @end    
    12.     
    13. #import "MyClass.h"    
    14. @implementation MyClass     
    15. -(int)addX:(int)x andY:(int)y    
    16. {    
    17.     return x + y;    
    18. }    
    19. @end    
    20.   
    21. ?声明实例变量或方法参数时可以指定协议名称  
    22.   
    23. @interface MyClass    
    24. {    
    25.     id<MyProtocol> myVar;     
    26. <!--EndFragment-->    
    27. }    
    28. @end    
    29.     
    30.     
    31. -(void) methodName:(id<MyProtocol>) obj    
    32. {    
    33.     //方法代码    
    34. }    
    35.   
    36. ?可以通过对象的conformsToProtocol:@protocol(协议名)来判断是否遵循某协议  
    37. [plain] view plaincopy  
    38. MyClass *mc = [[MyClass alloc] init];    
    39. BOOL flag = [mc confirmsToProtocol : @protocol(MyProtocol)];     
    40. //如果实现了协议,flag为真,未实现为假