一起学Objective-C - Protocols

来源:互联网 发布:网络论坛和网络社区 编辑:程序博客网 时间:2024/05/21 20:42

Protocols有点像Java中的interface, 但是要更加灵活一点。


Objective-C中有两种Protocol:

 非正式的Protocol -  非正式的Protocol在其他语言中基本找不到对应的概念,但是却很有用,之后再详细学习。

正式Protocol - 我们提供一个对象应该响应的方法列表(在编译器可以校验),在运行期也可以检查某个对象是否遵守了某个protocol. 正式Protocol 比较像Java中的interface.



声明正式Protocol 

一个正式Protocol声明了一系列的方法, 下例中的@protocol LinkedList <List>表明List是LinkedList的父Protocol , 它将继承所有的List中的方法。

@protocol List- (void) add:        (id) item;- (void) remove:     (id) item;- getAtIndex:        (int)idx;- (void) clear;@end@protocol LinkedList <List>- (void) addFirst:   (id)item;- (void) addLast:    (id)item;- getFirst;- getLast;@end



实现正式Protocol
如果你需要让一个类遵守一个Protocol, 你要在你的头文件(interface文件)中来声明,同时实现所有需要实现的方法。
@interface BiQueue <LinkedList>{  // instance variables ...}  // method declarations ...  // [don't need to redeclare those for the LinkedList protocol]- takeFirst- takeLast@end...@implementation BiQueue  // must implement both List's and LinkedList's methods ...- add:        (id) item{  // ...}- addFirst:   (id)item{  // ...}@end

如果需要你可以让一个类遵守多个Protocol, 可以像下例一样声明
@interface ContainerWindow < List, Window >  ...@end


实现文件中则需要包含两个Protocol中所有的方法。


使用Protocol

要使用一个正式Protocol, 只需要简单的像对象发Protocol中的消息。 如果你需要类型校验,有下面两种方式。

第一种你使用遵守了Protocol的类名来声明你的变量的类型

BiQueue queue = [[BiQueue alloc] init];  // send a LinkedList message[queue addFirst: anObject];


第二种方式需要使用下面这种特殊的语法。
// alternatively, we may stipulate only that an object conforms to the  // protocol in the following way:id<LinkedList> todoList = [system getTodoList];task = [todoList getFirst];...
这个例子我们只指明了Protocol,而没有指明具体是那个实现类。


如果你不确信返回的对象是否遵守了某个Protocol,你可以用下面的方法来进行校验
if ([anObject conformsToProtocol: aProtocol] == YES)  {    // We can go ahead and use the object.  }else  {    NSLog(@"Object of class %@ ignored ... does not conform to       protocol", NSStringFromClass([anObject class]));  }


最后,你可以像在头文件(interface)中声明的一样,来指明一个对象遵守了多个Protocol。
id <LinkedList, Window>   windowContainerOfUnknownClass;