Category是什么? 相对于java,Category是一个全新的概念,它为我们提供了区别于继承的另外一种方法来对类进行扩展。我们可以向任何已有的类(可以是你自己创建的类,可以是Foundation中的类,也可以是第三方的API)添加成员函数来实现功能上的扩展(注:category只允许添加成员函数,不能添加数据成员),添加的函数可以访问类中所有的数据成员,该类的子类也将继承新添加的成员函数。

如何定义一个Category?

07_category
07_category

这很像一个类的声明。不同的地方在于后面没有列出父类,并且在括号里面写了Categories的名称。分类的名字可以随便取,但是最好能表达出你在类目中包含的方法所要做的事。

创建一个Category.

例如我们想为之前定义的手机类(Phone)添加一个上网的功能,

Add Category
Add Category

Add Category
Add Category

声明Category扩展的方法:

@interface Phone (Internet)
-(void) surfingTheInternet:(NSString*) address;
@end

实现Category扩展的方法

#import "Phone+Internet.h"
@implementation Phone (Internet)
-(void) surfingTheInternet:(NSString *)address{
    NSLog(@"我在浏览网页:%@",address);
}
@end

然后在main.m中#import “Phone+Internet.h”即可调用扩展的surfingTheInternet方法.

#import  <Foundation/Foundation.h>
#import "Phone.h"
#import "IphonePhone.h"
#import "Phone+Internet.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        IphonePhone* iphone = [[IphonePhone alloc] init];
        [iphone surfingTheInternet:@"http://developer.apple.com"];
    }
    return 0;
}

Category的使用场景:

  1. 当你在定义类的时候,在某些情况下(例如需求变更),你可能想要为其中的某个或几个类中添加方法。
  2. 一个类中包含了许多不同的方法需要实现,而这些方法需要不同团队的成员实现
  3. 当你在使用基础类库中的类时,你可能希望这些类实现一些你需要的方法。

Category的局限性:

  1. Category可以访问原始类的实例变量,但不能添加变量,如果想添加变量,可以考虑通过继承创建子类。
  2. Category可以重载原始类的方法,但不推荐这么做,这么做的后果是你再也不能访问原来的方法。如果确实要重载,正确的选择是创建子类。
  3. 和普通接口有所区别的是,在分类的实现文件中可以不必实现所有声明的方法,只要你不去调用它。