黑馬程式設計師---oc 協議和代理
——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——-
一 介紹
Protocol就一個用途,用來宣告一大堆的方法(不能宣告成員變數),不能寫實現。
只要某個類遵守了這個協議,就擁有了這個協議中的所有方法宣告。
只要父類遵守了某個協議,那麼子類也遵守。
Protocol宣告的方法可以讓任何類去實現,protocol就是協議。
oc不能繼承多個類(單繼承)但是能夠遵守多個協議。繼承(:),遵守協議(< >)
基協議:是基協議,是最根本最基本的協議,其中聲明瞭很多最基本的方法。
協議可以遵守協議,一個協議遵守了另一個協議,就可以擁有另一份協議中的方法宣告。
oc裡面的協議和java中的介面(interface)十分相似,但是和介面不同的是:協議沒有父類也不能定義例項變數
二 使用
1、協議的定義
@protocol 協議名稱
// 方法宣告列表….
@end
#import <Foundation/Foundation.h>
// 定義了一個名叫MyProtocol的協議
@protocol MyProtocol <NSObject>
// @required 要求實現,不實現就會發出警告
// @optional 不要求實現
- (void)test4;
@required
- (void)test;
- (void )test2;
@optional
- (void)test3;
@end
2、如何遵守協議
1> 類遵守協議
@interface 類名 : 父類名 <協議名稱1, 協議名稱2>
@end
#import <Foundation/Foundation.h>
@protocol MyProtocol2;
// 遵守一個協議
@interface Dog : NSObject <MyProtocol2>
@end
2> 協議遵守協議
@protocol 協議名稱 <其他協議名稱1, 其他協議名稱2>
@end
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
// 一個協議遵守了另外一個協議,就可以擁有另一個協議的所有方法宣告
@protocol MyProtocol3 <MyProtocol>
- (void)hehe;
@end
3、協議中方法宣告的關鍵字
1> @required (預設)
要求實現,如果沒有實現,會發出警告
2> @optional
不要求實現,怎樣不會有警告
4、定義一個變數的時候,限制這個變數儲存的物件遵守某個協議
類名<協議名稱> *變數名;
id<協議名稱> 變數名;
NSObject *obj;
id obj2;
如果沒有遵守對應的協議,編譯器會警告
id<MyProtocol> obj4 = [[Person alloc] init];
5、
@property中宣告的屬性也可用做一個遵守協議的限制
@property (nonatomic, strong) 類名<協議名稱> *屬性名;
@property (nonatomic, strong) id<協議名稱> 屬性名;
@property (nonatomic, strong) Dog *dog;
@property (nonatomic, strong) id dog2;
6、協議可用定義在單獨.h檔案中,也可用定義在某個類中
#import "Dog.h"
// 把協議定義在該類中,因為該協議只在本類中呼叫。
@protocol MyDogProtocol <NSObject>
- (void)dogTest;
@end
@interface Hashiqi : Dog<MyDogProtocol>
- (void)addTest;
@end
@interface Hashiqi (Add)
- (void)addTest;
@end
2> 如果這個協議用在很多類中,就應該定義在單獨檔案中
三 協議的應用–代理模式
1、建立一個協議TicketDelegate
#import <Foundation/Foundation.h>
// 宣告一些跑腿方法
@protocol TicketDelegate <NSObject>
// 返回票價
- (double) ticketPrice;
// 還剩多少張票
- (int) leftTicketsNumber;
@end
2、建立一個代理NextAgent,並遵守TicketDelegate協議
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface NextAgent : NSObject<TicketDelegate>
@end
3、建立一個代理的實現類NextAgent.m,實現遵守的協議中的方法
#import "NextAgent.h"
@implementation NextAgent
- (double)ticketPrice
{
return 500;
}
- (int)leftTicketsNumber
{
return 10;
}
@end
4、建立一個Person類,其中有一個成員變數遵守協議TicketDelegate
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface Person : NSObject
- (void) buyTicket;
// 擁有一個代理屬性
// id代表代理的類名隨便
// 但必須遵守TicketDelegate協議
@property (nonatomic, retain) id<TicketDelegate> delegate;
@end
5、建立一個Person的實現類,實現相應的方法
#import "Person.h"
@implementation Person
// 買電影票
- (void)buyTicket
{
// 叫代理去幫自己買票(詢問一下票價、詢問一下票的剩餘張數)
double price = [_delegate ticketPrice];
int number = [_delegate leftTicketsNumber];
NSLog(@"通過代理的幫忙,票價=%f,還剩%d張票", price, number);
}
- (void)dealloc
{
[_delegate release];
[super dealloc];
}
@end
6、建立一個main函式,來進行測試
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Agent.h"
#import "NextAgent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// 建立Person物件
Person *p = [[[Person alloc] init] autorelease];
// 建立代理物件
NextAgent *a = [[[NextAgent alloc] init] autorelease];
// 設定人的代理
p.delegate = a;
// 呼叫人的buyTicket方法
[p buyTicket];
}
return 0;
}