Objective-C 编程语言(4)协议---非继承关系上的相似性,正式的协议,非正式的协议

转载请标明出处:http://blog.csdn.net/zhangxingping

非继承关系上的相似性

    如果多个类(两个或者以上)实现了相同的一套方法,那么这些类通常被划分到声明了这些共有方法的抽象类的下面,作为其派生类。不相关的类大多数情况下是不会实现有相似性的方法的。相反,有一定的相似性也不能成为两个类之间必须有继承关系的理由。例如,在程序中我们可能需要对象来表示XML文件,并从XML文件来对某些类的对象进行初始化:
    -(NSXMLElement *) XMLRepresentation;
    -initFromXMLRespresentation:(NSXMLElement *)xmlString;
    这些方法可以被划分到一个协议下面。实现了这个协议的多个类之间的这种相似性并不能说明什么(译者注:除了说明他们遵循同一个协议之外,不能因此就要求这些类之间有继承关系。因为遵循的协议所提供的方法只是这些类的部分功能而不是全部,并且这些类的数据部分在很多情况下都是大不相同的,也就是这些类所表示的实体之间是没有相似性的)。
    但是我们可以根据对象的类所遵循的协议来对对象进行分类,而不仅仅是可以根据他们的类型来分类。例如,一个NSMatrix类的实例必须和每一个单元格中的对象进行通信。一种实现方式就是从类的角度来考虑:矩阵单元格中的对象都是NSCell类的派生类型,这样所有单元格中的对象都继承了NSCell类中的方法,能响应NSMatrix中发送的消息。另外一种实现方式就是NSMatrix对象只要求其单元格中的对象有特定的方法集,以便响应自己发送的消息即可,而不用关心这些对象的类型。
    

正式的协议

    Objective-C提供了一种正式的声明协议中方法列表(包括声明属性)的方式。语言本身以及运行时系统都是支持正式协议的。比如,编译器可以基于协议来进行类型检查,对象也可以在运行时进行“自省”并报告自己是否遵守了某个协议。
    声明协议
    声明协议的时候使用@protocol命令字:
    @protocol 协议名称
    方法的声明
    @end
    比如,表示XML协议的声明如下:
    @protocol MyXMLSupport
    - initFromXMLRepresentation:(NSXMLElement *) XMLElement;
    -(NSXMLElement *)XMLRepresentation;
    @end
    协议中的可选方法
    协议中的方法可以通过命令字@optional来标记为是可选的。与之相对应的是命令字@required表示必须实现的方法,这个也是缺省的命令字。我们在程序中可以使用@required和@optional命令字来对协议中的方法按照自己喜欢的方式进行分组。如果没有使用任何命令字,缺省的将是@required.
    @protocol MyProtocol
    
    - (void) requredMethod;
    
    @optional
    -(void) anOptionalMethod;
    -(void) anotherOptionMethod;
    
    @required
    -(void)anotherRequiredMethod;
    
    @end
    注意:在Mac OS X v10.5中,协议是不支持可选的声明属性的。但是这种限制在Mac OS X v10.6以及以后的版本中被取消了。
        

非正式的协议

    除了上面提到的正式的协议之外,我们还可以通过把方法分组到类别(category)中;来定义非正式的协议:
    @interface NSObject ( MyXMLSupport )
    - initFromXMLRepresentation:(NSXMLElement *)XMLElement;
    -(NSXMLElement *)XMLRepresentation;
    @end
    非正式的协议通常都是作为NSObject类的类别出现的。因为这样就可以把这些方法和NSObject类的所有派生类关联上(实际程序中的大部分类都是作为NSObject类的派生类出现的。)。正是由于所有的类都是从NSObject这个根类派生而来的,因此非正式协议中的方法就不局限于继承关系图中的某写特定类了。(当然,我们可以把方法声明成为别的类的类别,但这样将使得这些方法只局限于该类在继承关系图的对应的分支上,实际中几乎不会这样去做。)
    当把类别当作非正式的协议使用的时候,类别中的接口不必有对应的实现。通常都是需要实现这些接口的类在其接口文件中再次声明这些方法,并在其实现文件中和别的方法一起实现。
    这种把类别当作非正式的协议使用的方法实际上是对类别的一种扭曲。这种方式声明了一组方法,但是没有把这些方法和任何特定的类或者实现关联起来。
    由于这种方式是非正式的,因此类别中声明的协议不是被广泛支持的。采用这种方法的协议在编译是没有类型检查,在运行时也不会检查对象是否遵守了该协议。如果需要用这些便利,我们必须使用正式的协议。这种非正式的协议也许会在所有的方法都是可选的时候比较有用。例如对于委托(delegate)来说就是如此。在Mac OS X v10.5和以后的版本中通常使用正式的协议会更好些。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值