1. 程式人生 > >黑馬程式設計師---oc 協議和代理

黑馬程式設計師---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;
}