------ android培训、java培训、期待与您交流! ----------
OC基础—protocol协议
1. protocol基本使用
就是用来声明方法的,而且可以交给任何类来使用,但是要遵守我的协议。
简单使用:我们先来声明一个protocol
#import <Foundation/Foundation.h>
// 定义了一个叫Myprotocol的协议
@protocol MyProrocol
// 声明一些方法
- (void)test;
- (void)test2;
@end
这样我们就定义了一个协议,现在我们建立一个类Person来遵守这个协议
#import <Foundation/Foundation.h>
// 既然要遵守这个协议那么就要导入这个协议
#import "MyProtocol.h"
// 只要一个类遵守了某分协议,就可以拥有这份协议中的所有方法声明
@interface Person : NSObject <MyProtocol>
@end
既然遵守了MyProtocol这个协议那么就可以拥有,这个协议中所有声明的方法,就不必在Person.h中再次声明,直接在.m文件实现就可以了
#import "Person.h"
@implementation Person
- (void)test
{
NSLog(@"调用了test方法");
}
- (void)test2
{
NSLog(@"调用了test2方法");
}
@end
而且就这样的写法,如果Person.m中没有全部实现协议中的方法会发出警告。
而且如果父类遵守了这份协议,那么子类一会遵守这份协议
2. @require,@optional
其实,协议中是有一些参数的(@require,@optional)
#import <Foundation/Foundation.h>
// 定义了一个名叫MyPropocol的协议
// 可以加一些关键字,方法是否要实现,默认必须实现
@protocol MyPropocol <NSObject>
@required // 要求实现,不实现就会发出警告
- (void)test;
@optional // 不要求实现
- (void)test2;
@end
@require:代表这个方法一定要在遵守协议的类中实现,不然会放出警告。
@optional:代表这个方法实不实现都是可以的,不会发出警告。
其实不实现都是可以的,程序照样运行,这样做的目的是增强程序员之间的交流,增强团队合作。
补充一点:
一个类可以遵守多份协议(继承的话,只能继承一个),就像这样:
@interface Person : NSObject <MyProtocol, MyProtocol2>
多个协议之间用 ,号隔开,而且会得到所有协议中方法的声明;
3. 协议间的遵守,基协议
NSObjcet是一个基类,最根本最基本的类,任何类都要继承他
基协议<NSObject>:这个则是最根本最基本的协议,任何协议要遵守它,基类NSObject遵守了基协议<NSObject>。
协议一是可以遵守一个协议的,像这样
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
// 一个协议遵守了另一个协议,就可以拥有这份协议中的所有方法声明
@protocol MyPropocol3 <MyPropocol>
@optional
- (void)haha;
@end
这样,MyProtocol就拥有了MyPropocol这份协议的方法,在此基础上自己还可以添加行的方法
4. 限制对象类型
如果我们需要某一个对象遵守我们的协议,那么我们可以这样写
// Obj保存的对象必须遵守MyPropocol这个协议
//NSObject<MyPropocol> *obj = [[NSObject alloc] init];
NSObject<MyProtocol> *obj = [[Person alloc] init];
这样在我们对象的后面加上我们要遵守的协议NSObject<MyProtocol>那么这个创建的对象必须遵守我们的规定的协议,不然,我们的编译器就会发出警告。
我们也可以在.h文件的成员变量中使用协议,如:
@interface Person : NSObject <MyProtocol, MyProtocol>
@property (nonatomic, strong) id<MyProtocol> Obj;
@end
那么,我们在为obj用set方法付一个对象的时候,如果这个对象没有遵守规定的协议那么,就会发出警告。
5. 协议的提前声明
在我们的.h文件中,我们也可以使用像@class Dog;这样来提前声明一个协议,这样做的好处就不说了,降低耦合性。
我们使用的关键字是@protocol,看一下
#import <Foundation/Foundation.h>
//#import "MyPropocol.h"
//#import "MyPropocol2.h"
//#import "MyPropocol3.h"
@class Hsshiqi;
@protocol MyProtocol2;
@protocol MyProtocol;
@protocol MyProtocol3;
// 只要一个类遵守了某一份协议,就能拥有这份协议中的所有方法声明
// : 继承父类
// <> 遵守协议
@interface Person : NSObject <MyProtocol2, MyProtocol3>
@property (nonatomic, strong) id<MyProtocol2> Obj;
@property (nonatomic, strong) Hsshiqi *dog;
@end
这样,我们就不用用#import导入了,在.m文件用到的时候在导入就可以了。
6. 总结一下
propocol(协议): 用来声明一大堆方法,只要某个类遵守了这个协议,就可以调用这些方法,父类遵守,子类也遵守。
一个类可以遵守多个协议。
1. 协议的定义
@protocol 协议名称 <NSObject
>
// 方法声明
@end
2. 如何遵守协议
1> 类遵守协议
@interface 类名 :父类名 <NSObject>
@end
2> 协议遵守协议
@protocol 协议名称 <其它协议名称1,其它协议名称2>
@end
3. 协议中方法声明的关键字
1> @required (默认)
要求实现,不实现,有警告
2> @optional
不要求实现
4. 定义一个变量的时候,限制这个变量保存的对象遵守摸个协议
类名<协议名称> *变量名;
id<协议名称> 变量名;
NSObject<MyProtocol> *obj3 = [[Person alloc] init];
// NSObject * = id
id<MyProtocol> obj4 = [[Person alloc] init];
如果没有遵守对应的协议,编译器会警告
5. @protocol中声明的属性也可以遵守协议的限制
6. (补充设计问题)(分类也可以)
协议可以定义在其他文件中也可以定义在单独的.h文件中
1》 如果这个协议只用在某个类中,应该定义在该类中
2》 如果这个协议用在多个类中,应该定义在单独的类中
3. 协议中方法声明的关键字
1> @required (默认)
要求实现,不实现,有警告
2> @optional
不要求实现
4. 定义一个变量的时候,限制这个变量保存的对象遵守摸个协议
类名<协议名称> *变量名;
id<协议名称> 变量名;
NSObject<MyProtocol> *obj3 = [[Person alloc] init];
// NSObject * = id
id<MyProtocol> obj4 = [[Person alloc] init];
如果没有遵守对应的协议,编译器会警告
5. @protocol中声明的属性也可以遵守协议的限制
6. (补充设计问题)(分类也可以)
协议可以定义在其他文件中也可以定义在单独的.h文件中
1》 如果这个协议只用在某个类中,应该定义在该类中
2》 如果这个协议用在多个类中,应该定义在单独的类中