------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、分类(Category)概念及使用流程
1、类别的概念及作用
1)、类别概念
Category有很多种翻译:分类\类别\类目(一般叫分类)
Category是OC特有的语法,其他语言没有的语法(类似于C#语言中的“扩展方法”和“partial”关键字)
2)、类别的作用
在不修改原有的类的基础上增加新的方法;
一个庞大的类可以分模块开发;
一个庞大的类可以由多个人来编写,更有利于团队合作。
3)、使用类别的目的
①对现有类进行扩展:比如,你可以扩展Cocoa touch框架中的类,你在类别中增加的方法会被子类所继承,而且在运行时跟其他的方法没有区别。
②作为子类的替代手段:不需要定义和使用一个子类,你可以通过类别直接向已有的类里增加方法。
③对类中的方法归类:利用category把一个庞大的类划分为小块来分别进行开发,从而更好的对类中的方法进行更新和维护。
2、使用类别的步骤
先声明类别--->实现类别--->使用类别
Person base --张三 (Person+base)
eat run
playgame--李四(Person+playgame)
playlol,playdota
study --麻子 (Person+study)
studyc studyios
注意:类别的命名规则:类名+扩展方法,如“NSString+countNum”。
类别的接口声明与类的定义十分相似,但类别不继承父类,只需要带有一个括号,表明该类别的主要用途。
二、分类(Category)声明和实现
1、声明和实现一个类别
在.h文件中,声明类别:
@interface ClassName (CategoryName)
NewMethod; //在类别中添加方法
//不允许在类别中添加变量
@end
说明:声明类别格式
1)新添加的方法必须写在@interface 与 @end之间;
2)ClassName 现有类的类名(要为哪个类扩展方法);
3)CategoryName 待声明的类别名称;
4)NewMethod 新添加的方法。
注意:
1)不允许在声明类别的时候定义变量
在.m文件中(也可以在.h中实现),实现类别:
@implementation ClassName(CategoryName)
NewMethod
{
……
}
@end
说明:实现类别格式
1)新方法的实现必须须写在@implementation与@end之间;
2)ClassName 现有类的类名;
3)CategoryName 待声明的类别名称;
4)NewMethod 新添加的方法的实现。
2、调用类别中的方法
与一般成员方法调用形式,完全一样,需要包含类别的头文件
三、分类的使用注意事项
1、分类注意事项
(1)、分类只能增加方法, 不能增加成员变量、@property(可能编译不报错,但是运行有问题)
#import <Foundation/Foundation.h>
@interface Person :NSObject
{
@public
int _age;
}
-(void)eat;
-(void)run;
@end
@interface Person (study)
@property int age;
-(void)study;
-(void)work;
-(void)run;
@end
@implementation Person
-(void)run{
NSLog(@"person---age = %d",_age);
}
-(void)eat{
NSLog(@"---person---");
}
@end
@implementation Person (study)
-(void)study{
NSLog(@"---study---");
}
-(void)run{
NSLog(@"study---age = %d",_age);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool{
Person*p = [Person new];
[p eat];
[p study];
[p run];
p.age = 10;
p->_age = 20;
}
return 0;
}
编译时不报错
运行时报错
(2)、分类可以访问原来类中的成员变量;
#import <Foundation/Foundation.h>
@interface Person :NSObject{
@public
int _age;
}
-(void)run;
@end
@interface Person (study)
-(void)study;
@end
@implementation Person
-(void)run{
NSLog(@"Person---age = %d",_age);
}
@end
@implementation Person (study)
-(void)study{
//分类可以访问原来类中的成员变量
NSLog(@"study---age = %d",_age);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool{
Person *p = [[Person alloc]init];
p->_age = 10;
[p run];
[p study];
}
return 0;
}
运行结果
(3)、如果分类和原来类出现同名的方法,优先调用分类中的方法, 原来类中的方法会被忽略。
#import <Foundation/Foundation.h>
@interface Person :NSObject
{
@public
int _age;
}
-(void)run;
@end
@interface Person (study)
-(void)run;
@end
@implementation Person
-(void)run{
NSLog(@"person---age = %d",_age);
}
@end
@implementation Person (study)
-(void)run{
NSLog(@"study---age = %d",_age);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool{
Person*p = [Person new];
p->_age = 10;
[p run];
}
return 0;
}
运行结果
2、分类的编译顺序
当多个分类中有同名方法,则执行最后编译的文件方法。