非正式协议:Foundation框架里给NSObeject类增加新的功能,这个类别叫做非正式协议
在OC中能否让一个类必须实现某一个方法?怎么做?
OC中interface是一个类的头文件声明,一般写在一个.h头文件中,并不是真正意义上的接口的意思,接口由一个叫做协议protocol来实现的
协议的作用:供其他类遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法
2.Protocol使用流程
定义一大堆方法没有实现
定义一个协议--->在类中采用指定的协议
--->实现协议中的方法(注意方法有必须实现和选择实现的两种)
1).定义协议(协议默认的要采纳NSObject的协议)
@protocol xxx <NSObject>默认情况下遵守NSObject协议
@end
2).采纳协议(1).类遵守协议创建类的时候遵守某个或者某几个协议
3).实现协议的方法
@interface类名:NSObject<XXX>
@end
或
@interface类名:NSObject<XXX,BBB,CCC>
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(intargc, const char* argv[]) {
@autoreleasepool {
Person * p = [Person new ];
[p run];
[p eat];
[p work];
}
return 0;
}
#import<Foundation/Foundation.h>
@protocol baseProtocol <NSObject>
-(void)eat;
-(void)run;
@end
#import <Foundation/Foundation.h>
//导入协议的头文件
#import "baseProtocol.h"
#import "workProtocol.h"
//遵守协议 遵循多个协议
@interface Person : NSObject<baseProtocol,workProtocol>
//当我们遵守了某个协议后 ,就相当于这个协议所有方法的声明
@end
#import "Person.h"
//协议中的所有方法都得实现
@implementation Person
-(void)eat{
NSLog(@"长的漂亮又能吃");
}
-(void)run{
NSLog(@"长的漂亮又能跑步");
}
-(void)work{
NSLog(@"我正在工作");
}
@end
#import <Foundation/Foundation.h>
@protocol workProtocol <NSObject>
-(void)work;
-(void)findJob;//定义不实现会出现警告
@end
Protocol使用注意
1.声明一大堆的方法,不能声明成员变量,不能写实现
2.只要遵守某个协议,就拥有了这个协议的所有方法声明
3.只要父类遵守了某个协议,子类也遵守(继承)
3.Protocol声明的方法可以让任何类实现,protocol就是协议
5.oc不能多继承,一个类可以遵守多个协议 ,继承( : ),遵守协议 (< >)
6.基协议:<NSObject >最基本的协议
7.协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明
Protocol其他用法
1.子类继承父类的protocol协议中的方法
Protocol基协议
NSObject是一个基类,<NSObject>是一个基本协议
Protocol中@required (表示必须实现的方法)和 @optional(表示可选择的)
默认情况下是@required都是必须要实现的
#import <Foundation/Foundation.h>
#import "Dog.h"
int main(intargc, const char* argv[]) {
@autoreleasepool {
Dog *d = [Dognew];
[d eat];
[d run];
[d fight];
}
return 0;
}
#import <Foundation/Foundation.h>
@protocol baseProtocol <NSObject>
@required
-(void)run;
-(void)eat;
@optional
-(void)fight;
@end
#import <Foundation/Foundation.h>
#import "baseProtocol.h"
@interface Dog : NSObject<baseProtocol>
@end
#import <Foundation/Foundation.h>
@protocol baseProtocol <NSObject>
@required
-(void)run;
-(void)eat;
@optional
-(void)fight;
@end
因为fight方法没有实现,所以报错
@protocol类型限制
#import <Foundation/Foundation.h>
#import "Girl.h"
#import "Dog.h"
#import "houseHold.h"
int main(intargc, const char* argv[]) {
@autoreleasepool {
Dog *dog = [Dognew];
Dog *dog2 = [Dognew];
Girl *girl = [Girl new];
//id<houseHold> obj = dog;//Dog 类没有继承houseHold协议
//第一种类型限制
id<houseHold>obj2 = girl;
[obj2 wash];
[obj2 cook];
// Girl<houseHold> *obj3 = dog;//表示Girl对象必须是girl对象,而且要遵循houseHold协议
//第二种类型限制
Girl<houseHold> *obj4 = girl;//表示Girl对象必须是girl对象,而且要遵循houseHold协议
[obj4 wash];
[obj4 cook];
//第三种类型限制 女孩养了一只狗
obj4.dog = dog2;
//如果Dog类没有遵循<calculatorProcotol>协议就会报错
///Users/chingwei_macpc/Documents/第八个知识点Protocol协议/@protocol情境限制/main.m:32:18: Incompatible pointertypes assigning to 'Dog<CalculatorProtocol> *' from 'Dog *'
}
return 0;
}
#import <Foundation/Foundation.h>
@protocol houseHold <NSObject>
@required
-(void)wash;
-(void)cook;
@optional
-(void)haveJob;
@end
#import <Foundation/Foundation.h>
@protocol CalculatorProtocol <NSObject>
-(void)calculator;
@end
#import <Foundation/Foundation.h>
#import "houseHold.h"
#import "Dog.h"
@interface Girl : NSObject<houseHold>
@property Dog<CalculatorProtocol>*dog;
@end
#import "Girl.h"
@implementation Girl
-(void)wash{
NSLog(@"妹子会洗衣服");
}
-(void)cook{
NSLog(@"妹子会做饭");
}
@end
#import <Foundation/Foundation.h>
#import "CalculatorProtocol.h"
@interface Dog : NSObject<CalculatorProtocol>
@end
#import "Dog.h"
@implementation Dog
@end
Protocol代理模式引入
#import <Foundation/Foundation.h>
#import "Baby.h"
#import "Nanny.h"
int main(intargc, const char* argv[]) {
@autoreleasepool {
Nanny *na1 = [Nanny new];
Baby *bay = [Baby new];
bay.blood = 30 ;
bay.sleep =20 ;
bay.nanny1 = na1;
[bay wantEat];
[bay wantSleep];
NSLog(@"sleep:%.2fblood :%.2f",bay.sleep,bay.blood);
}
return 0;
}
#import <Foundation/Foundation.h>
@class Baby;
@protocol babySitterProtocol <NSObject>
-(void)feedBabyEat:(Baby*)baby;
-(void)watchBaby:(Baby*)baby;
@end
#import <Foundation/Foundation.h>
@class Nanny;
#import "babySitterProtocol.h"
@interface Baby : NSObject
@property (nonatomic,assign) float blood;
@property (nonatomic,assign) float sleep;
@property (nonatomic,strong) Nanny<babySitterProtocol>*nanny1;
-(void)wantEat;
-(void)wantSleep;
@end
#import "Baby.h"
#import "Nanny.h"
@implementation Baby
-(void)wantEat{
NSLog(@"baby 在哭");
//保姆要喂她吃
[self.nanny1 feedBabyEat:self];
}
-(void)wantSleep{
NSLog(@"baby想睡觉了");
[self.nanny1 watchBaby:self];
}
@end
#import <Foundation/Foundation.h>
#import "babySitterProtocol.h"
@interface Nanny : NSObject<babySitterProtocol>
@end
#import "Nanny.h"
#import "Baby.h"
@implementation Nanny
-(void)feedBabyEat:(Baby*)baby{
baby.blood += 20 ;
NSLog(@"保姆正在喂婴儿吃东西 体力值为:%.2f",baby.blood);
}
-(void)watchBaby:(Baby*)baby{
baby.sleep += 10 ;
NSLog(@"保姆正在哄婴儿睡觉 体力值 :%.2f",baby.sleep);
}
@end
代理模式图如下
MVC模式
代理模式概念
代理模式应用场合
UI控件大多数时候都在使用代理模式
@protocol使用补充
1.在.h文件中 @protocol 协议名;
2.在.m文件中导入 #import "协议名.h"
3.在main.m文件中导入 #import "协议名.h"
#import <Foundation/Foundation.h>
#import "baseProtocol.h"
#import "Dog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Dog *dog = [Dog new];
[dog run];
}
return 0;
}
#import <Foundation/Foundation.h>
//#import "baseProtocol.h"
@protocol baseProtocol ;
@interface Dog : NSObject<baseProtocol>
@end