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

协议(Protocols)

协议定义了可以由任何类实现的方法。协议至少在以下三种情况下是非常有用的:
    ● 声明希望由别人实现的方法 
    ● 声明对象对外的接口而隐藏自身的类(型)
    ● 捕获在继承关系图上不相干的类之间的共性

声明由别人实现的接口

类(class)以及类别(category)中声明的都是和某个特定的类相关的方法,主要都是由类自己实现的方法。然而,协议声明的是和具体的类不相干的,可以由任何别的类实现的方法。
    简单地说协议声明了一个方法列表,不和任何类的定义相关。例如,用于报告用户鼠标动作的方法可以形成一个协议:

    -(void)mouseDown:(NSEvent*)theEvent;-(void)mouseDragged:(NSEvent*)theEvent;-(void)mouseUp:(NSEvent*)theEvent;

任何相对用户鼠标动作做出反应的类都可以遵循这个协议并实现这些方法。
    协议使得方法的声明脱离了类的继承关系,因此它可以以一种与类(class)和(category)不同的方式来使用。协议中声明的方法可能都是在别的地方实现的。实现了这些方法的类不是重点,重点是一个特定类是否遵循了某些协议,也就是说这个类是否实现了协议中定义的那些方法(译者注:也就是说通常我们不关心某个协议都有那些类实现了,而是会关心某个类遵循了那些协议)。这样一来,对象的分类就不仅仅是可以根据他们所属的类在继承关系上的相似性了,还可以根据他们对应的类遵循相同协议的相似性。在继承关系图上位于不同分支的类可能是不相干的,但是从协议的角度来说可能是相似的,因为他们有可能实现了相同的协议。
    协议在面向对象的设计中,特别是当一个项目被分割成多个实现部分或者是需要和别的项目中的对象配合工作的时候显得特别重要。Cocoa中的框架大量地使用了协议来通过Objective-C消息支持进程间的通信。
    然而Objective-C程序中并不是都要使用协议。和类的定义以及消息表达式不同的是,协议只是提供了一种选择。一些Cocoa框架中使用了协议,一些就没有用到。这完全取决于任务本身的需要。

由别人来实现的方法

如果我们知道对象的类,我们可以通过查看这个类的接口声明知道该对象可以响应那些消息。类的接口声明就表明了其对象可以接收什么样的消息。协议同样也提供了一种表明该类的对象可以接收什么消息的方式。
    通信是双方的。对象可以发送消息也可以接收消息。例如,一个对象可以委托另外的对象来完成某种特定的操作,也可以只是简单地向别的对象请求所需的信息。在某些情况下,一个对象可能需要通知别的对象自己的状态发生变化了,以便别的对象可以采取必要的措施。
    如果消息的接收者和发送者是在同一个项目中(或者是有人已经向你提供了消息接收者及其接口文件),那么这种通信的协调是很容易的。发送者只需要引入接收者的接口文件。接口文件中就声明了发送者在发送消息时使用的方法选择器。
    然而,如果我们开发的对象需要发送消息给还没有定义好的对象,也就是由别人来实现的对象,我们就没有接口文件。此时我们就需要别的方式来声明我们发送消息中的还没有实现的方法。协议就可以满足这样的要求。协议告诉了编译器该类中使用的方法,同时也通知别的实现部分他们应该定义这些方法以便他们能和该类协调很好地工作。

假设我们程序中的对象需要通过发送helpOut:消息及其别的消息来请求别的对象的帮助,那么我们的类中可以声明一个assistant实例变量来表示这些消息的接收者,并定义一个伴生的方法来设置该实例变量的值。这个伴生的方法使得别的对象可以注册成为我们程序中消息的接收者:

    -setAssistant:anObject{assistant = anObject;}

然后,当我们想要给assistant发送消息的时候,我们可以检查该对象是否可以响应这样的消息:

    -(BOOL) doWork{...if([ assistant respondsToSelector:@selector(helpOut:)] ){[ assistant helpOut:self];return YES;}return NO;}

由于在编写上述代码段的时候,我们还不知道什么样的对象会注册成为assistant,我们只能为helpOut:方法声明一个协议。我们不用引入实现该协议的类的接口文件。

为匿名对象声明接口

协议可以被用来声明匿名对象的接口,也就是不知道类型的对象的接口。匿名对象可以代表一种服务或者是一定功能的函数的集合,特别是当程序中只需要该类的一个对象的时候。在应用程序中,必须在使用前进行初始化的、定义了程序架构的重要的类和对象通常都不适合以匿名的方式出现(言外之意,通常只有那些功能有限,并且是在特定场合才使用的非通用类及其对象才比较合适以匿名的方式出现)。
    对象对于其开发人员来说都不是匿名的。但是当其开发者将其提供给别人的时候,这些对象通常是匿名的。例如,考虑如下的情形:
    ● 提供给别人使用的框架或者是一系列对象中可以包含不能通过类名或者接口文件而确定类型的对象(即使用者无法知道这些对象的确切类型)。由于不知道类名及其接口文件,使用者就无法创建该类的实例。相反,可以由框架或者函数的提供者提供一个现成的实例。通常都是由另外一个类的方法返回一个可用的这样的匿名对象:

      id formatter = [receiver formattingService];

上面方法返回的就是一个没有类类型标识的对象。但是为了保证这个对象是可用的,该方法的提供者至少需要曝露出该对象可以响应哪些消息。此时就可以通过把该对象和其方法关联起来形成一个列表,即协议来实现。
    ● Objective-C消息是可以被发送给远端对象的(remote objects)----别的程序中的对象。(《Objective-C运行时编程指南》的“远端消息”一节中以更加详细的方式阐述了这种可能性)。
      每一个程序中都有自己的结构体,类以及内部的逻辑。但是我们没有必要知道别的程序是如何工作的或者是我们需要和其中的那个部件进行通信。作为外部人员,我们只需要知道可以发送什么消息,给谁发消息就可以了。
      当一个应用程序发布其中的一个对象作为远端消息的接收者的时候,还要发布一个协议,其中声明了这个对象可以响应的消息,而不需要声明关于该对象的任何其他信息。发送消息的应用程序也没有必要知道该对象的类型,更不能在自身的设计中使用到这种类型;它所需要知道的就是这个对象遵循的协议。
    协议使得匿名对象成为了可能。没有协议,就没有方法来声明对象的接口而不感知该对象的类型。

    注意:尽管匿名对象的提供者没有向外界揭示该对象的类型,在运行时该对象是可以自己揭示自身的类型的。一个类消息就可以返回该匿名对象的类。然而,实际中通常很少有必要揭示这种多余的信息;只要知道对象遵循的协议就足够了。
    

Objective-C 编程语言(4)) 协议---声明由别人实现的接口,由别人来实现的方法,为匿名对象声明接口相关推荐

  1. 【Golang第8章:面向对象编程】Go语言的结构体是什么,怎么声明;Golang方法的调用和声明;go语言面向对象实例,go语言工厂模式;golang面向对象的三大特性:继承、封装、多态

    介绍 这个是在B站上看边看视频边做的笔记,这一章是Glang面向对象编程 这一章内容较多,内容有Go语言的结构体是什么,怎么声明:Golang方法的调用和声明:go语言面向对象实例,go语言工厂模式: ...

  2. 【贪玩巴斯】Unity初学圣经Part2-C#基础——Day 01:C#基础之——命名空间、类、方法、变量的声明赋值和相关知识以及.NETC#关系讲解 2022年3月28日

    C#基础之--命名空间.类.方法.变量的声明赋值和相关知识以及.NETC#关系讲解 对应视频4-1至4-7 1.引入命名空间: 2.引入类.方法 3.变量的声明赋值 4.综合小练习 5. .NET的介 ...

  3. Go 学习笔记(34)— Go 方法声明、方法调用、方法值、方法表达式、切片对象方法、指针对象方法

    1. 方法声明 Go 语言的方法非常纯粹, 可以看作特殊类型的函数, 其显式地将对象实例或指针作为函数的第一个参数, 并且参数名可以自己指定, 而不强制要求一定是 this 或 self .这个对象实 ...

  4. 面向对象(类的概念,属性,方法,属性的声明,面向对象编程思维

    1 面向对象 1.1 你是如何认识新事物的? 从过往的事物中总结事物的特点(特征),并比对新事物,把新事物进行归类. 1.2 类(Class)的概念(A) 类是对一组具有相同特征和行为的对象的抽象描述 ...

  5. 【Kotlin】Kotlin 单例 ( 懒汉式 与 恶汉式 | Java 单例 | Kotlin 单例 | 对象声明 | 伴生对象 | get 方法 | ? 与 !! 判空 )

    文章目录 I . 单例的懒汉式与恶汉式 II . Java 中的懒汉式与恶汉式 III . Kotlin 中对应 Java 的懒汉式与恶汉式 IV . Kotlin 对象 ( object ) 声明 ...

  6. 不愿意和别人打交道_不想麻烦别人,也不希望别人麻烦我,是什么心理?看完就明白...

    阅读本文前,请您先点击上面的"蓝色字体",再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注. 注:本文转载自网络,侵删 ...

  7. 声明对象_计算机各语言数据类型及对象声明之区别

    各语言数据类型 JS中数据类型有:整数型.浮点型.String.布尔型.转义字符.未定义.空值(null) JAVA中数据类型有: byte short int long float double b ...

  8. android对象申明,Kotlin中的对象表达式和对象声明的具体使用

    Kotlin的对象表达式与Java中的匿名内部类的主要区别:匿名内部类只能指定一个父类型,但对象表达式可以指定0~N个肤类型. 一.对象表达式 对象表达式的语法格式如下: object [: 0~N个 ...

  9. Kotlin学习笔记 第二章 类与对象 第十二 十三节 对象表达式与对象声明 类型别名

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

最新文章

  1. 2022-2028年中国完全生物降解塑料产业发展动态及投资前景预测报告
  2. 计算机动画制作 实验要求,A074计算机动画制作实验——动画制作初步
  3. 【错误记录】发布 Flutter 插件包报错 ( ‘gmail.com‘ has insufficient permissions to upload new versions of package)
  4. android记账本统计_记账送老婆啦!初音 蕾姆 随便挑随便选| iOS 安卓
  5. 夫妻两一个两年内3张卡9次逾期,一人4次,还能办理房贷吗?
  6. Linux中设置vim自动在运算符号两边加上空格
  7. java匿名内部对象_JavaSE 学习参考:匿名内部类和匿名对象
  8. LeetCode(832)——翻转图像(JavaScript)
  9. 这个 SpringCloud+Vue 在线教育系统,牛得起飞!
  10. markdown在Windows10下安装后启动出现的错误以及一些解决方案
  11. 集体智慧编程——协同过滤
  12. COMSOL(1)寻找最小曲面
  13. 23 - OAI NSA gNB搭建 - 博一
  14. 计算机应用程序没声音,电脑没有声音怎么办,五个步骤解决电脑没声音
  15. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2版本正式发布
  16. win7计算机无法识别分辨率,window7分辨率显示不正常
  17. 【Excel实战】--目录及链接
  18. adb devices后显示List of devices attached/unauthorized问题解决
  19. postman---postman参数化
  20. Mac 下截图聚焦、局部放大、按键 GIF 录屏的最佳实践

热门文章

  1. 谷歌最新多模态模型CoCa,多项任务取得SOTA效果,ImageNet达到91.0%
  2. Web时代,电脑用户的求生之路
  3. 微三国介绍及超级简单入门玩法
  4. jQuery日历插件FullCalendar使用方法
  5. 一起来看流星雨剧情简介/剧情介绍/剧情分集介绍第三十六集
  6. FPGA学习之深入浅出玩转FPGA
  7. ssm+mybatis+mp
  8. Power BI学习笔记
  9. 实例操作:Python提取雅虎财经数据,并做数据分析和可视化
  10. linux挂载实验箱闹钟,Linux/Ubuntu命令行下打造一个音乐闹钟