一:Category 分类
先了解一下继承的缺陷:高耦合性,就是说使用继承关系来扩成一个类,如果父类的一些东西改变,那么子类将受到严重的影响,甚至不能用
1:Category(分类,类别):能够帮助我们扩展一个类的功能,就是说如果你想给一个写好的类添加一些方法,就可以使用category,说白了就是给原类添加方法的,这在实际的开发当中也是比较好用的一人负责一个模块,把自己需要并且原类中没有的方法加进去。
2:分类中不能定义成员变量
3:只要是在原类中定义的成员变量,不管是private还是protected等都可以再分类中直接访问
4:如果分类中定义并实现了与原类相同的方法,那么原类中的方法相当于被覆盖掉了,想调用原类中的方法,把分类给注释掉就可以了,实际开发当中不要覆盖原类中的方法,因为你事往原类中添加方法的,没有必要修改,一修改可能会影响整个系统
下面我们来看一个实例,创建一个Person对象,写了Person的连个基本方法eat和drink,然后我们创建了一个分类BlackPerson用来写黑人的方法,mian函数中如下:
//创建一个Person对象
Person *p = [[Person alloc]init];
//[p eat];
//分类的方法
[p blackEat];
Person的.h文件
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
@private int _age;
}
@property(nonatomic,assign)int age;
@property(nonatomic,strong)NSString *name;
//人类的基本行为
-(void)eat;
-(void)drink;
//然后我们把黑人和白人的方法分别用分类来创建
@end
Person的.m文件
#import "Person.h"
@implementation Person
-(void)eat
{
NSLog(@"正常人吃");
}
-(void)drink
{
NSLog(@"正常人喝");
}
@end
分类BlackPerson的.h文件
#import "Person.h"
@interface Person (BlackPerson)
//不能再分类中声明成员变量
//{
// int height;
//}
-(void)blackEat;
-(void)blackDrink;
@end
分类BlackPerson的.m文件
#import "Person+BlackPerson.h"
@implementation Person (BlackPerson)
-(void)blackEat
{
//在分类的方法中调用原类的方法可以用self关键字
[self eat];
[self setAge:10];
//下面这个_age 默认是私有的,必须要再原来中声明才能用(测试显示声明成私有的也可以直接用)
_age = 20;
NSLog(@"黑人吃东西");
}
-(void)blackDrink
{
NSLog(@"黑人喝东西");
}
//如果分类中定义实现了与原类相同的方法,原类中的方法相当于被覆盖掉了
//-(void)eat
//{
// NSLog(@"子类覆盖了父类吃的方法");
//}
//如果多个分类都重写了父类的方法,那么显示的结果跟编译顺序有关(了解一下即可)
@end
二:分类的应用
再我们的实际开发当中分类很多时候都是用在 扩展系统给我们的类
下面我们来用分类扩展NSString类的一个方法:查找一个字符串中的数字个数#import <Foundation/Foundation.h>
#import "NSString+NSStringCount.h"
//再我们的实际开发当中分类很多时候都是用在 扩展系统给我们的类
int main(int argc, const char * argv[]) {
@autoreleasepool {
//我们来扩展一个NSString类,给它添加一个再字符串中查找数字个数的方法
NSString *str = @"df234k";
int num = [NSString numberCountOfString:str];
NSLog(@"num为 %i",num);
NSLog(@"调用类方法的结果会是这样:%i",[@"sdf34534d" numberOfCount]);//这一句相当于下面两句
// NSString *str2 = @"sdf34534d";
// NSLog(@"调用类方法的结果会是这样:%i",[str2 numberOfCount]);
}
return 0;
}
分类NSStringCount的.h文件
#import <Foundation/Foundation.h>
@interface NSString (NSStringCount)
//类方法用类调用
+(int)numberCountOfString:(NSString *)str;
//对象方法,用对象调用,下面这个方法为什么不需要参数呢?先考虑考虑,这是因为这个方法是对象方法,你的string本身就是个字符串对象肯定不需要传了,用self即可
-(int)numberOfCount;
@end
分类NSStringCount的.m文件
#import "NSString+NSStringCount.h"
@implementation NSString (NSStringCount)
+(int)numberCountOfString:(NSString *)str
{
//一定要初始化为0,不然会报错
int count = 0 ;
for (int i= 0; i<str.length; i++) {
unichar c = [str characterAtIndex:i];
if (c>='0'&&c<='9') {
count++;
}
}
return count;
}
/*
注意!!!!!,有了下面的方法之后上面的方法就可以简写成这样,这在我们的开发当中经常会用到,把特别常用的或者经常需要重复用到的方法单独抽出来写成一个方法,方便调用,而且方便易懂
@implementation NSString (NSStringCount)
+(int)numberCountOfString:(NSString *)str
{
return [str numberOfCount];
}
*/
-(int)numberOfCount
{
int count = 0 ;
for (int i= 0; i<self.length; i++) {
unichar c = [self characterAtIndex:i];
if (c>='0'&&c<='9') {
count++;
}
}
return count;
}
@end