黑马程序员--OC自学笔记---09 protocol

本文详细介绍了Objective-C中的协议概念及其使用方法,包括协议的定义、采纳及限制等,并通过实例展示了如何利用协议实现代理设计模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


1.   Protocol的概念

类似于java中的接口的作用,定义一些方法,让其他类去实现。

Protocol是一些方法的声明,一般写到一个.h的头文件中,这些方法供其他的类去遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法。


2.   Protocol的使用流程

定义协议----->在类中采用指定的协议---->实现协议中的方法(方法有必须实现和选择实现两种)


3.   协议的定义

@protocol 协议名称<NSObject>  默认遵守NSObject协议

//方法声明列表

@end

注意:协议默认的要采纳NSObject的协议


4.   采纳协议

记得导入协议的头文件。

1)        类遵守协议

创建类的时候遵守某个或某几个协议

@interface 类名:父类名<协议名称1,协议名称2……>

@end

2)        协议遵守协议

某个协议也遵守某个或者某些协议,一个协议可以遵守其他多个协议

@protocol 协议名称<其他协议名称1,其他协议名称2……>

声明方法列表;

@end


5.   协议的基本使用

#import <Foundation/Foundation.h>
//协议baseProtocol
@protocol baseProtocol <NSObject>
-(void)run;
-(void)eat;
@end
 
//Person类遵守baseProtocol协议
#import <Foundation/Foundation.h>
//导入协议的头文件
#import "baseProtocol.h"
//遵守协议
@interface Person : NSObject<baseProtocol>
@end
#import "Person.h"
@implementation Person
//实现协议中必须要实现的方法
-(void)eat{
   NSLog(@"长得漂亮又能吃,叫吃货;长得丑又能吃,叫饭桶。");
}
-(void)run{
   NSLog(@"running");
}
@end
 
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
   @autoreleasepool {
     
       Person *p = [Person new];
       [p eat];
       [p run];
   }
   return 0;
}


6.   protocol使用注意

1)        protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现。

2)        只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。

3)        只要父类遵守了某个协议,那么子类也遵守。

4)        Protocol声明的方法可以让任何类去实现,protocol就是协议。

5)        OC不能继承多个类(单继承),但是能够遵守多个协议。

6)        基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。

7)        协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明。

8)        协议也可以采纳其他协议

9)        类如果采纳协议后,实现了协议的方法,这些方法时可以被子类继承的。


7.   Protocol基协议

NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它,它还有名字也叫NSObject的协议,它是一个基协议,最根本最基本的协议。

建议每个新的协议都要遵守NSObject协议。


8.   Protocol中的@required和@optional

@required和@optional是协议方法声明中的两个关键字,它们主要用于控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流。

     

 @protocol base<NSObject>
      @required//可以省略,默认为@required,表示必须要实现的方法
      -(void)run;
      -(void)eat;
      @optional   //不能省略,表示可选择实现的方法
      -(void)fly;
      @end

9.   Protocol类型限制

1)        使用id存储对象时,对象的类型限制

Id <协议名称>变量名

id <myProtocoll>obj

含义为定义的这个obj对象必须要遵守myProtocol协议


2)        对象赋值时的类型限制

格式:类名<协议名称>*变量名

NSObject<myProtocol>*obj

含义为定义的这个obj对象必须为NSObject类型的,而且要遵守myProtocol协议。


3)        对象关联关系下,对象的类型限制

对象A的实例变量中包含B的对象,对B进行声明时需要让B遵守一定的协议。


10. Protocol代理设计模式举例


以保姆和婴儿为例,婴儿饿了保姆要喂婴儿吃东西,婴儿困了保姆要哄婴儿睡觉。

//协议
#import <Foundation/Foundation.h>
@class Baby;
@protocol lookBabyProtocol<NSObject>
//喂婴儿吃东西
-(void)letBabyEat:(Baby *)baby;
//哄婴儿睡觉
-(void)letBabySleep:(Baby *)baby;
@end
 
//婴儿类
#import <Foundation/Foundation.h>
#import "lookBabyProtocol.h"
@class BaoMu;
@interface Baby : NSObject
@property (nonatomic,assign)intblood;  //婴儿的体力值
@property (nonatomic,assign)intsleep;  //婴儿的睡眠值
//婴儿的代理---保姆
@property (nonatomic,strong)BaoMu<lookBabyProtocol>*bm;
-(void)forEat;
-(void)forSleep;
@end
#import "Baby.h"
#import "BaoMu.h"
@implementation Baby
//婴儿想吃东西
-(void)forEat{
   NSLog(@"forEat...");
   [self.bm letBabyEat:self];
}
//婴儿想睡觉
-(void)forSleep{
   NSLog(@"forSleep...");
   [self.bm letBabySleep:self];
}
@end
 
//保姆类
#import <Foundation/Foundation.h>
#import "lookBabyProtocol.h"
@class Baby;
//保姆要遵守协议
@interface BaoMu :NSObject<lookBabyProtocol>
@end
#import "BaoMu.h"
#import "Baby.h"
@implementation BaoMu
//喂婴儿吃东西
-(void)letBabyEat:(Baby *)baby{
   NSLog(@"baby is eating~~");
   baby.blood+=10;
}
//哄婴儿睡觉
-(void)letBabySleep:(Baby *)baby{
   NSLog(@"baby is sleeping~~");
   baby.sleep+=15;
}
@end
 
//主函数
#import <Foundation/Foundation.h>
#import "Person.h"
#import "lookBabyProtocol.h"
#import "Baby.h"
#import "BaoMu.h"
int main(int argc, const char * argv[]) {
   @autoreleasepool {
       //定义对象
       Baby *baby = [Baby new];
       BaoMu *baomu = [BaoMu new];
       //让婴儿有一个保姆
       baby.bm = baomu;
       //初始化婴儿的体力值和睡眠值
       baby.blood = 20;
       baby.sleep = 12;
       //婴儿想吃东西
       [baby forEat];
       //婴儿想睡觉
       [baby forSleep];
       NSLog(@"baby.blood = %d,baby.sleep =%d",baby.blood,baby.sleep);
   }
   return 0;
}


11. Protocol代理设计模式

1)        概念

传入的对象,代替当前类完成了某个功能,称为代理模式。

利用协议实现代理模式的思路:

①   定义一个协议,里面声明代理类需要实现的方法列表

②  创建一个代理类,遵守上面的代理协议

③  在需要代理的类中,定义一个对象类型为id,且遵守代理协议的成员变量(delegate)

④  在需要代理的类中调用成员变量(delegate)的方法,调用代理类的方法。

⑤  在main.m或其他使用需要代理的类的文件中,为这个类的成员变量(代理类)赋值

2)        代理设计模式应用场合

①  通知的场合:当对象A发生了一些行为,想告知对象B(让对象B成为对象A的代理对象)

②  监听器场合:对象B想监听对象A的一些行为(让对象B成为对象A的代理对象)

③  有些事情,不想自己处理,想交给别人处理

当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象)。

3)        代理模式设计,学生通过中介找房子

//创建协议
#import <Foundation/Foundation.h>
@protocol findHouseProtocol<NSObject>
-(void)findHouse;
@end
 
//代理类遵守协议
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
@interface LinkHome :NSObject<findHouseProtocol>
@end
#import "LinkHome.h"
@implementation LinkHome
-(void)findHouse{
   NSLog(@"链家正在帮您找房子。");
}
@end
 
 
//学生类
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
@interface Student : NSObject
//定义一个类型为id,遵守协议的成员变量
@property (nonatomic,strong)id<findHouseProtocol>delegate;
-(void)needHouse;
@end
#import "Student.h"
@implementation Student
-(void)needHouse{
   NSLog(@"学生需要找房子");
   //调用成员变量(代理)的方法
   [self.delegate findHouse];
}
@end
 
 
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
#import "Student.h"
#import "LinkHome.h"
int main(int argc, const char * argv[]) {
   @autoreleasepool {
      //创建对象
        Student *stu = [Student new];
       
       LinkHome *lh = [LinkHome new];
       //给成员变量赋值
       stu.delegate = lh;
       
       [stu needHouse];
   }
   return 0;
}
 


12. @property的使用

1)        在要遵守协议的类中可以使用@property 协议名称;的格式,引入要遵守的协议,而不使用#import,这和@class作用一样,只是告诉编译器这是一个协议,但协议里面有哪些方法不知道。

2)        在遵守协议的类中使用@property后,需要再.m文件中使用#import引入协议的头文件。

3)        在main函数中,也要导入协议的头文件

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌影~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值