协议只有方法的声明(类似于其他编程语言的接口)
协议相当于大家都所遵循的
关键字 @protocol 协议名 <所遵循的协议> 默认NSObject
@end
@protocollamcoProtocol <NSObject>
@required //必须实现的方法
-(void)study;
@optional //可实现可不实现的方法
-(void)work;
@end
student.h文件
#import<Foundation/Foundation.h>
#import"lamcoProtocol.h"
@interfaceStudeny :NSObject<lamcoProtocol,bank>
@end
student.m文件
#import"Studeny.h"
@implementationStudeny
-(void)study{
NSLog(@"%s",__func__);
}
//-(void)work{
// NSLog(@"%s",__func__);
//}
@end
主函数:
#import<Foundation/Foundation.h>
#import"Studeny.h"
#import"OtherStudent.h"
intmain(intargc,constchar* argv[]) {
@autoreleasepool{
Studeny*stu=[[Studenyalloc]init];
// [stu study];
//判断其是否遵循协议
if([stuconformsToProtocol:@protocol(lamcoProtocol)]) {
//判断协议是否有该方法
if([sturespondsToSelector:@selector(study)]){
[stustudy];
// [stu work];
}else{
NSLog(@"找不到好工作");
}
}else{
NSLog(@"没有参加培训");
}
if([stuconformsToProtocol:@protocol(lamcoProtocol)]){
if([sturespondsToSelector:@selector(giveMoney)]) {
NSLog(@"每月还钱");
}else{
NSLog(@"成为黑户");
}
}else{
NSLog(@"不关事");
}
}
return0;
}
为类创建了私有方法,实现一对多
1个.m对应多个.h文件
就是说一个类的 .m文件可以有多个延展的.h文件
延展可以进行成员变量,属性,方法的各种操作
延展文件MyClass_add.h
#import"MyClass.h"
@interfaceMyClass()
-(void)add;
@end
类文件:Myclass.h
#import<Foundation/Foundation.h>
@interfaceMyClass :NSObject
-(void)select;
@end
Myclass.m
#import"MyClass.h"
@implementationMyClass
-(void)select{
NSLog(@"%s",__func__);
}
-(void)add{
NSLog(@"%s",__func__);
}
@end
主函数 main.m
#import<Foundation/Foundation.h>
#import"MyClass.h"
//到导入延展的头文件
#import"MyClass_add.h"
intmain(intargc,constchar* argv[]) {
@autoreleasepool{
MyClass*class=[[MyClassalloc]init];
[classselect];
[classadd];
}
return0;
}
1.不能在分类中添加属性,只能添加方法
2.如果再分类里面使用@property,那么它只能生成getter和setter的声明,没有实现
3.如在在分类中写了与本类同名的方法,优先调用分类里面的方法,所以在分类中定义类的时候,尽量避免和本类中的方法重名
4.在分类里面可以访问本类里面所定义的属性
例子:目录
主函数main.m
#import<Foundation/Foundation.h>
#import"NSString+CategoryNSString.h"
intmain(intargc,constchar* argv[]) {
@autoreleasepool{
NSString*str=@"abc";
NSLog(@"%@", [str Reverser]);
NSLog(@"%d",[str leng].intValue);
}
return0;
}
类目文件:NSString+CategoryNSString.h
#import<Foundation/Foundation.h>
@interfaceNSString (CategoryNSString)
-(NSString*)Reverser;
-(NSNumber*)leng;
@end
类目文件:NSString+CategoryNSString.m
#import"NSString+CategoryNSString.h"
@implementationNSString (CategoryNSString)
/**
* 字符串反转函数
*
* @param string传入的字符串
*
* @return逆序后的字符串
*/
-(NSString*)Reverser{
NSMutableString*str=[NSMutableStringstring];
for(unsignedlongi=(self.length); i>0; i--) {
[strappendFormat:@"%c",[selfcharacterAtIndex:i-1]];
}
returnstr;
}
/**
* 把字符串长度int类型变成NSNumber类型
*
* @param string出入的字符串
*
* @return NSNumber,字符串的长度
*/
-(NSNumber*)leng{
NSNumber*num=[[NSNumberalloc]initWithUnsignedLong:self.length];
returnnum;
}
@end
类目的优化
把所有的分类都放到一个分类中MyClass.h
#import<Foundation/Foundation.h>
@interfaceMyClass :NSObject
-(void)Select;
@end
@interfaceMyClass (CategoryUpdate)
-(void)update;
@end
@interfaceMyClass (CategoryAdd)
-(void)add;
@end
@interfaceMyClass (CategoryDeleta)
-(void)delect;
@end
MyClass.m文件
#import"MyClass.h"
@implementationMyClass
-(void)Select{
NSLog(@"%s",__func__);
}
@end
MyClass+CategoryAdd.m文件
#import"MyClass.h"
@implementationMyClass (CategoryAdd)
-(void)add{
NSLog(@"%s",__func__);
}
@end
MyClass+CategoryUpdate.m文件
#import"MyClass.h"
@implementationMyClass (CategoryUpdate)
-(void)update{
NSLog(@"修改");
}
@end
MyClass+CategoryDeleta.m文件
#import"MyClass.h"
@implementationMyClass (CategoryDeleta)
-(void)delect{
NSLog(@"删除");
}
@end
总结:1.为了避免更多的代码,和类目的扩展,把类目的.h文件中全部放在要扩展的类中,并且把他们对应的.h文件删除 2.第二步把类目中相之对应的.m文件,把他们的
#import"MyClass+CategoryDeleta” 全部改成本来的类 如:#import "MyClass.h" 就可以了
#import ,@class ,#include三者之间的区别
#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。
@class就是两个类之间的相互引用
@class的作用是告诉编译器,有这么一个类,用吧,没有问题
@class还可以解决循环因爱的问题,例如A.h中导入了B.h,而B.h导入了A.h,每一个头文件的编译都要让对象先编译成功才行,使用@class就可以避免这种情况的发生
object-c中的类目,延展,协议
原文:http://www.cnblogs.com/qianLL/p/5235682.html