类别(Catagory)
类别是扩展对象能力的一种方法。你可以在对象中添加新的method,但你不能添加新的实例变量。新的method被视为扩展的类的一部分,子类将继承这些新的method。如果你有两个覆盖一个类的method的类别,究竟哪一个覆盖并不确定。
类别的语法与类的语法相似。他们都有interface和实现。当然,也有一些轻微的差别。类别定义的开头几行象这样:
@interface ClassName (CatagoryName)
@implementation ClassName (CatagoryName)
ClassName是你要扩展的类的名称,CatagoryName是类别的识别的名称。类别可以访问所扩展的类的实例变量。
其余的语法是相同的:在interface中声明method,在实现中定义它们,并以@end结束。
你可以用类别建立私有method。把类别的interface放在类的实现文件的实现代码的前面。然后把你需要作为私有mthod的放在这个类别中。创建对象的实现,然后,在这个文件的末尾,加入类别的实现。这样可以对外隐藏这些method,如果在其他地方试图访问这些method,编译器将会给出警告。它不能够在运行时避免被访问,而只能在编译时警告你。在ObjC中没有办法禁止method被访问。
协议(Protocol)
协议,顾名思义,定义一组类之间相互遵守的行为规范。协议没有interface和实现,但他们与interface更加相似。你不需要添加新的实例变量,也不添加新的method或定义任何method的内部实现。协议所需要做的只是定义一套要求所有类都必须包含的method,以遵循这个协议。
协议在你使用ObjC的动态类型机制的时候特别有用。ObjC拥有和Java类似的运行时的动态类型。这是它优于C++的一点,C++只支持“编译时”的动态类型。
比如你要创建一个可以接受任何对象的method。你必须确定这个对象可以响应你要发送的消息,否则你将会发送这个对象不明白的消息给它。这会导致一些问题。如果你使用了协议,你就可以确保它能响应你将要发给它的许多消息,如果你仅是需要发送一个消息,你还有其它方法来检查……这一点我留给你自己去研究。
同时,在上述的情况中,你还可以使协议要求你所期望的参数。我现在会展示给你看怎么完成这些工作。
定义一个新的协议,首先:
@protocol ProtocolName
接着是任意数量的method的声明,请使用在interface定义的相同的语法。最后以@end结束。
现在,为了遵循这个协议,你首先声明你要创建的新对象的interface的内容。然后,你必须在这个对象的实现中定义协议中的所有method。
@interface NewObject : Object
上述的语句告诉编译器这是一个叫NewObject的对象,它的超类是Object,并要符合ProtocolName的协议。
要查询一个对象是否满足特定的协议,可以使用“conformsTo"的mthod。
[object conformsTo:@protocol(ProtocolName)];
这会根据对象是否符合的情况返回YES或NO。
要查询一个参数是否符合特定的协议,可以象如下地声明method:
-method:(id)argument;
(译注:原文如此,在gcc中似乎并不支持,按照逻辑来说应该为:-method:(id ) argument;)
你也可以返回满足协议的对象:
-(id ) method;
以下转自:zhiwei.li博客
Protocol
参考资料为 Programming in Objective-C 2.0 第2版(Pearson教育出版集团 2009)
简介:
Objective-C里的Protocol 与Java的Interface(接口) 或者 C++的purely virtual class(纯虚类)相同 ,就是用来 声明接口的
协议是 被许多类 共享的 方法的列表. 列在协议里的方法不负责实现;目的是让别人来实现(比如你).协议提供一种定义一组同特定的名称相关的方法的途径. 这些方法一般放在文档中,让你知道它们如何执行, 一般你能够在自己的类定义里 实现它.
如果协议中定义的方法有 @optional 指令, 如:
@protocol Drawing
-(void) paint;
-(void) erase;
@optional
-(void) outline;
@end
如何列在@otpional后面的方法都是 可选的, 也就是说不一定要实现它.上例中, 采纳Drawing这个协议的类,不是非要实现outline这个方法不可
如果是@required指令的后面的方法呢,那是一定要实现的
协议
协议声明那些由其他类实现的方法。协议至少在以下3个方面是有用的
1)声明那些期望由其他类实现的方法
2)为隐藏它的类的那些对象声明接口
3)为那些没有继承关系的类捕获它们之间的相同点
为其他类声明接口
Class和category接口 声明那些与特定的类相关的方法。
非正式协议和正式协议,声明的方法是与任何特定的类无关的
协议就是一个简单的方法声明的列表,不与类定义关联。举个例子,下面这些方法用来
报告用户的鼠标行为的,可以被收集到一个协议里:
- (void)mouseDown:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
如果哪个类想要响应鼠标事件,那么就可采纳这个协议,实现这些方法。
因为协议与类的继承体系无关,所以可以用那些class和categories都不能使用的方式。
协议列出的那些方法被实现(或者可能被实现)在其他地方。不关心实现这些方法的类的实体,而关心是否有一个特殊的类 服从这个协议—-是否实现了协议定义的那些方法。
Catagory
想为现有的类添加新的行为时,通常会创建子类。如果没有源代码,便无法创建子类。但是可以通过创建Categories来实现。