先说说类目和延展分别有什么作用和区别:
分类的作用:
是给没有.m文件的类扩展方法(如NSString类),不能添加实例变量。但是可以通过添加属性,改写setter和get方法,通过runtime的关联方法来实现类似添加实例变量的效果。
runtime参考链接:http://blog.csdn.net/u014220518/article/details/52873164
分类中扩展的方法是原有类的一部分,原有类以及子类都可以使用
在分类中定义了和原有类同名的方法,调用的时候优先执行分类中定义的方法
延展的作用:
是帮助有.m文件的类管理私有实例变量和方法
通过延展定义的方法属于私有方法,外界是不能访问的,只能在当前.m文件中使用
区别:
分类是为没有.m的类做扩展,不做实例变量扩展,只有方法扩展,把一个类的方法扩展到多个类中。延展是为有.m的类做扩展,只在自己的.m文件中操作,既可以扩展实例变量,也可以扩展方法。
分类中扩展的方法可以在外界通过本类调用,延展扩展的实例变量和方法只能在自己.m中使用,即使是自己子类也不能使用。
创建分类和延展:
创建分类:command+n新建 -> Object-c file -> file type(category) ;class选择要为其创建分类的类。这里我选择了NSString,file名字写str。
创建完毕多出一个类为:NSString+str
添加延展:新建一个类,例如继承与NSObject的Person类。在Person.m中添加
@interface Person ()
//这里添加属性和方法
@end
下面直接上代码
分类的使用:
NSString+str.h文件
#import@interface NSString (Str)
-(void)printHello;//自定义一个printHello方法
-(NSComparisonResult)compare:(NSString *)string;//改写系统原有的方法compare
-(NSString *)getFirstChar;//自定义一个获取第一个字符并大写的方法
+ (void)printyes;
@end
NSString+str.m文件
#import "NSString+Str.h"
@implementation NSString (Str)
-(void)printHello{
NSLog(@"hello");
}
-(NSComparisonResult)compare:(NSString *)string{
NSLog(@"我被改写了");
return 0;
}
-(NSString *)getFirstChar{
NSString *s=[self substringToIndex:1];
return [s uppercaseString];
}
+(void)printyes {
NSLog(@"yes");
}
@end
Person.h文件(下面两块代码在一起)
#import<Foundation/Foundation.h>
@interface Person : NSObject
// 声明一个可供外界调用的sayYES方法
- (void) sayYES;
@end
// Student继承自Person
@interface Student : Person
// 声明一个公开方法saya
-(void)saya;
@end
Person.m文件(下面三块连在一起)
#import "Person.h"
// 延展
@interface Person (){
NSString *sex;//声明了一个实例变量sex
}
// 声明一个属性
@property (nonatomic,assign) NSInteger a;
// 个人感觉在这里声明私有方法没什么意义,反正也无法在外界调用,那么直接在@implementation @end里面实现方法就行了,不用再在延展里声明。
-(NSString *)getSex;//声明一个getSex方法
-(void)sayHi;// 声明sayHi方法
+(void)sayHello; // 声明一个sayHello的类方法
@end
@implementation Person
// 这个方法没有在延展里声明,直接实现。
-(void)sayNO{
NSLog(@"NO");
}
-(NSString *)getSex{//实现getSex方法
return @"nv";
}
-(void)sayHi{
sex = @"nv";
NSLog(@"hi%@",sex);
}
+(void)sayHello {
NSLog(@"hello");
}
// sayYES方法可供外界使用
-(void)sayYES{
NSLog(@"我是sayYES方法");
[self sayHi];
[Person sayHello];
[self sayNO];
}
@end
@implementation Student
//子类Student不能使用实例变量sex
- (void)saya{
[self sayYES];
[self sayHi];
[self sayNO];
}
- (void)sayb{
NSLog(@"bb");
//可以发现父类的成员变量sex子类也不能用
// NSLog(@"bb %@",sex);
}
@end
main.m文件
#import#import "NSString+Str.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
//分类中扩展的方法是原有类的一部分,原有类以及子类都可以使用
//在分类中定义了和原有类同名的方法,调用的时候优先执行分类中定义的方法
[NSString printyes];
NSString *string=[[NSString alloc] init];
[string printHello];//NSString类有了printHello方法
NSMutableString *mutableString=[[NSMutableString alloc]init];
[mutableString printHello];//子类NSMutableString类也有了printHello方法
int a=[@"123" compare:@"234"];
NSLog(@"%d",a);
NSLog(@"str=%@",[@"abc" getFirstChar]);//输出A
// Person类方法和对象方法都无法调用延展里的方法 并且其子类也无法继承使用Person类延展里的方法
Person *p=[[Person alloc]init];
[p sayYES];
Student *stu =[[Student alloc] init];
// Person的子类Student的对象stu只能调用Person类的公开方法sayYES方法,延展里的方法都不可用。
[stu sayYES];
// stu只可以调用Student类的公开方法saya方法
[stu saya];
return 0;
}