一、protocol(协议)相似java中的接口,定义了一些类须要公用到的方法,只要遵照这个协议,就能够拥有这些方法并能够去实现它们,这样能够避免许多重复的代码。
java
好比,一个Teacher(老师)类,一个Student(学生)类
ui
老师有goToClassroom(去教室),goToToilet(去厕所),goToOffice(去办公室)等方法,学生也有
atom
这样Teacher类和Student类都须要声明重复的代码
spa
Teacher.hssr
#import <Foundation/Foundation.h> @interface Teacher : NSObject - (void)goToClassroom; - (void)goToToilet; - (void)goToOffice; @end
Student.h代理
#import <Foundation/Foundation.h> @interface Student : NSObject - (void)goToClassroom; - (void)goToToilet; - (void)goToOffice; @end
实现方法我就不实现了,若是这时有个协议来制定这些方法,让Teacher和Student都去遵照的话,就不须要重复这么多代码
code
SchoolDaily.horm
#import <Foundation/Foundation.h> @protocol SchoolDaily <NSObject> - (void)goToClassroom; - (void)goToToilet; - (void)goToOffice; @end
这时Teacher和Student只须要遵照SchoolDaily协议并实现协议里的方法便可拥有这些方法对象
Teacher.h接口
#import <Foundation/Foundation.h> #import "SchoolDaily.h" @interface Teacher : NSObject <SchoolDaily> @end
Student.h
#import <Foundation/Foundation.h> #import "SchoolDaily.h" @interface Student : NSObject <SchoolDaily> @end
二、@required表明协议里的方法必须实现,不然编译器会警告,不写默认是@required,@optional表明协议里的方法是选择实现
好比,goToOffice方法Student能够选择不实现
SchoolDaily.h
#import <Foundation/Foundation.h> @protocol SchoolDaily <NSObject> @required - (void)goToClassroom; - (void)goToToilet; @optional - (void)goToOffice; @end
三、协议能够与代理模式相结合
代理模式:委托(delegate),顾名思义就是委托别人办事,就是当一件事情发生后,本身不处理,让被人来处理。
a、在不使用delegate时,Teacher在修改做业前须要Student帮他收做业,则须要拥有学生这个变量
b、学生拥有pickupHomeWork(收做业)这个方法
c、老师拥有checkHemoWork(改做业)这个方法
Student.h
#import <Foundation/Foundation.h> @interface Student : NSObject - (void)pickupHomework; @end
Student.m
#import "Student.h" @implementation Student - (void)pickupHomework { NSLog(@"学生收做业"); } @end
Teacher.h
#import <Foundation/Foundation.h> #import "Student.h" @interface Teacher : NSObject @property(nonatomic, strong) Student *stu; - (void)checkHomework; @end
Teacher.m
#import "Teacher.h" @implementation Teacher - (void)checkHomework { // 叫学生帮他收做业 [_stu pickupHomework]; // 本身修改做业 NSLog(@"老师修改做业"); } @end
d、可是,Teacher和Student的耦合性太强,若是有一天这个Student毕业了,换成了Student2来收做业,Teacher类里要修改的代码也很多
f、使用代理的话,Teacher里就不须要修改代码,只须要把Student换成Student2便可
g、因而老师写了一份协议,只有遵照此协议的才能当他的课表明,才能够去收同窗的做业
Homework.h
#import <Foundation/Foundation.h> @protocol Homework <NSObject> - (void)pickupHomework; @end
Teacher.h
#import <Foundation/Foundation.h> #import "Homework.h" @interface Teacher : NSObject @property (nonatomic, strong) id<Homework> delegate; - (void)checkHomework; @end
Teacher.m
#import "Teacher.h" @implementation Teacher - (void)checkHomework { // 叫学生帮他收做业 [_delegate pickupHomework]; // 本身修改做业 NSLog(@"老师修改做业"); } @end
接下来不管是Student仍是Student2还有其余阿猫阿狗类,只要遵照老师的协议就能够有权利去收做业了
Student.h
#import <Foundation/Foundation.h> #import "Homework.h" @interface Student : NSObject <Homework> @end
Student.m
#import "Student.h" @implementation Student - (void)pickupHomework { NSLog(@"学生收做业"); } @end
须要注意如下几点:
1.id能够表示任何一个ObjC对象类型,类型后面的”<协议名>“用于约束做为这个属性的对象必须实现该协议(注意:使用id定义的对象类型不须要加“*”)
2.在.h文件中若是使用了另外一个文件的类或协议咱们能够经过@class或者@protocol进行声明,而没必要导入这个文件,这样能够提升编译效率
3.在编写代码中,协议代理文件一般以Delegate结尾,由于Delegate是代理的英文,这样作方便之后的管理和交接
4.代理协议文件中必定要包含基协议<NSObject>