八. oc基础知识(Protocal)
protocal 出发点:他仅仅是用来声明方法的。
1. 可以用来声明一大堆方法(但是不能声明成员变量)
2. 只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明
3. 只要父类遵守了某个协议,就相当于子类也遵守了
4. 协议列出了一组方法,有些是必须实现的,有些是选择实现(@optional)。遵守协议就要实现协议里面所有必须实现的方法。
1. 定义一个协议
协议格式的编写
@protocol协议名称//为协议起一个有意义的名称
// 方法声明列表
@end
2. 某个类遵守一些协议
@interface 类名 : 父类 <协议名称1,协议名称2,...>
/ / ...code...
@end
方法声明的关键字
协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
@required:这个方法必须要实现(若不实现,编译器会发出警告)
@optional:这个方法不一定要实现
协议遵守协议
1. 一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开
2. 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
@protocol 协议名称 <协议1, 协议2>
@end
基协议
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
NSObject协议中声明很多最基本的方法,比如description、retain、release等
建议每个新的协议都要遵守NSObject协议
基类是遵守基协议的。
@property 中申明的属性也可以作为一个遵守协议的限制
@property (nonatomic,strong) 类名<协议名称> *类型指针
协议的位置
协议可以直接写在类里面,写在@interface之前,这样就可以直接用了而不用在#import了,当只有这个类使用这个协议时,可以将协议写在里面。当然也可以定义在外部的某个.h文件中
协议的代理模式
@property (nonatomic,strong) 类名<协议名称> *类型指针,可以看出想传入数据那么这个数据必须是符合这个协议的,不然会出现错误,这样就可以放宽传入数据的类型,只要是符合条件的都可以传进来。下面是我写的一个
关于代理模式的小例子
main.m
1 // 2 // main.m 3 // Protocal终极练习 4 // 5 // Created by keeganlee on 15/2/11. 6 // Copyright (c) 2015年 keeganlee. All rights reserved. 7 // 10 11 #import <Foundation/Foundation.h> 12 #import "Student.h" 13 #import "Agenta.h" 14 #import "Agentb.h" 15 #import "MyprotocalB.h" 16 int main(int argc, const char * argv[]) { 17 @autoreleasepool { 18 19 id<MyprotocalA> agenta=[[Agenta alloc] init]; 20 21 id<MyprotocalB> agentb=[[Agentb alloc] init]; 22 23 24 Student *stu=[Student new]; 25 26 stu.d=agenta; 27 28 [stu buyTicket]; 29 30 stu.d=agentb; 31 32 [stu buyTicket]; 33 34 35 36 } 37 return 0; 38 }
person。h
// // Person.h // Protocal终极练习 // // Created by keeganlee on 15/2/11. // Copyright (c) 2015年 keeganlee. All rights reserved. // #import <Foundation/Foundation.h> #import "MyprotocalB.h" @interface Person : NSObject <MyprotocalB> @property (nonatomic,assign) int age; @end
Person.m
// // Person.m // Protocal终极练习 // // Created by keeganlee on 15/2/11. // Copyright (c) 2015年 keeganlee. All rights reserved. // #import "Person.h" @implementation Person @end
Student.h
#import "Person.h" @interface Student : Person @property (nonatomic,strong) id<MyprotocalB,MyprotocalA> d;//因为是id类型,在student的实现时,用遵循这个协议的类的对象调用特有的方法肯定是通不过的~~但是这时候加上这个协议,就相当于告诉编译器这里面有这些方法 可以使用。所以编译器就准许通过!!~ - (void)buyTicket; @end
Student.m
#import "Student.h" @implementation Student -(void)buyTicket { int c=[_d ticketRemain];//这里虽然没有agent两个类的。h文件但是编译器仍然可以认识这个具体方法 这就是接口的好处!! NSLog(@"There has %d ticket left~",c); [_d confirmToBuy]; } @end
Agenta.h
#import <Foundation/Foundation.h> #import "MyprotocalB.h" @interface Agenta : NSObject <MyprotocalB> @end
Agentb.h
#import <Foundation/Foundation.h> #import "MyprotocalB.h" @interface Agentb : NSObject <MyprotocalB> @end
Agenta.m
#import "Agenta.h" @implementation Agenta -(int)ticketRemain { return 100; } -(void)confirmToBuy { NSLog(@"OK~~!! you have got the ticket~~"); } @end
Agentb.m
#import "Agentb.h" @implementation Agentb -(int)ticketRemain { return 1000; } -(void)confirmToBuy { NSLog(@"SORRY ~All ticekt has been solded~~~~~"); } @end
Myprotocala
#import <Foundation/Foundation.h> @protocol MyprotocalA <NSObject> - (int) ticketRemain; - (void) confirmToBuy; @end
Myprotocalb
#import <Foundation/Foundation.h> #import "MyprotocalA.h" @protocol MyprotocalB <NSObject,MyprotocalA> @end
上面这个例子实现的是一个买票程序的代理模式,其中融合了继承,多态等前面学过的好多知识。(在比较晦涩难懂的地方都加上了注释)