【转载请注明出处】

1、接口的实现

对于接口这一概念的支持,不同语言的实现形式不同。Java中,由于不支持多重继承,因此提供了一个Interface关键词。而在C++中,通常是通过定义抽象基类的方式来实现接口定义的。

Objective-C既不支持多重继承,也没有使用Interface关键词作为接口的实现(Interface作为类的声明来使用),而是通过抽象基类和协议(protocol)来共同实现接口的。

2、接口的意义

面向对象编程中一条重要的经验法则是:对接口编程,而不是对实现编程。即一个对象想要调用另一个对象的方法,往往不会直接采取直接调用的形式。为降低耦合度考虑,通常会在调用者和被调用者中间增加一层抽象的(通常不会变动的)中间层,接口就是中间层的最通用的形式。

3、Objective-C中的接口与协议protocol

如前所述,Objective-C中使用协议protocol作为支持接口实现的关键词。

如下类A的对象想要调用类B的对象的方法:

Class A中:

- (void)doSth:(B *)b

{

  [b doSth];

}

增加一个抽象的(通常不会变动的)中间层作为中介,如下:

定义一个protocol:

@protocol doSthDelegate

(void)doSth;

@end

Class A中:

- (void)doSth:(id<doSthDelegate>) delegate

{

  if (delegate)

  [delegate doSth];

}

4、Objective-C中的接口与抽象基类

协议protocol其实是足以支持接口的语法实现的,但对于需要频繁调用的方法来说,未免不够简洁。如在NSObject协议中声明的alloc、dealloc、retain、release和autoRelease等几乎出现在iOS开发各个角落的方法,如果都需要

if (delegate && delegate respondsToSelector:@selector(func)

{
  [delegate func];

}

那就太过麻烦了。因此NSObject Class出现了。

在NSObject中对NSObject protocol中的方法都做了基本的实现,因而保证了处于NSObject派生链中的子类在调用NSObject protocol中的方法时的可靠性。写法上也变得极为简洁。

5、抽象基类和协议共存

如4中所述,抽象基类相比于协议,一方面提供了一些方法的基本实现,使得子类不需要重复实现,另一方面能够保持语法的简洁。因此,只使用协议而不使用抽象基类,是可行的,但极不方便。

而单独使用抽象基类支持接口的语法,是基本上不可行的。如SDK中的UIView及其子类,由于Objective-C的单继承限制,这些已经有基类的类,就不能使用接口了。当然,开发者自行定义的类,是可以完全依靠抽象基类进行组织的。

6、抽象基类和协议如何协作

经典范例就是标题中的NSObject class和NSObject protocol。

在Cocoa Touch中,并非所有的类都派生自NSObject,如NSProxy类(它本身是一个root class)。但是,对NSProxy和NSproxy的派生类的对象的内存控制,仍然采用alloc、dealloc、retain、release和autoRelease是很自然的想法。在不改变NSProxy基类的情况下,就只能通过协议来支持。

在NSObject协议中,声明了retain、release和autoRelease方法(alloc和dealloc在NSProxy有定义),而NSProxy实现了NSObject协议(conform to protocol NSObject),因此可以做到

[proxyObj release];

这样的调用。

7、总结

在Objective-C中,接口的支持主要由协议protocol来实现,抽象基类用于简化语法、提供通用方法的基础实现。

参考:

【1】Objective-C编程之道

【2】NSObject class and protocol

http://objectmix.com/c/177917-nsobject-class-protocol.html

【3】NSProxy Class Reference

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSProxy_Class/Reference/Reference.html

NSObject class和NSObject protocol的关系(抽象基类与协议)的更多相关文章

  1. 6、面向对象以及winform的简单运用(抽象基类与接口)

    抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例: ab ...

  2. C# 面向对象 , 抽象基类

    抽象基类 关键字,  abstract abstract class SSS { public void aaa() { } } 作为抽象基类, 只能在 继承关系 中 担任父类的角色,不能出现在其他地 ...

  3. thrift之TTransport类体系原理及源码详细解析1-类结构和抽象基类

    本章主要介绍Thrift的传输层功能的实现,传输的方式多种多样,可以采用压缩.分帧等,而这些功能的实现都是相互独立,和上一章介绍的协议类实现方式比较雷同,还是先看看这部分的类关系图,如下: 由上面的类 ...

  4. guxh的python笔记七:抽象基类

    1,鸭子类型和白鹅类型 1.1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__ ...

  5. 【Python】【元编程】【从协议到抽象基类】

    """class Vector2d: typecode = 'd' def __init__(self,x,y): self.__x = float(x) self.__ ...

  6. c++之——抽象基类

    在一个虚函数的声明语句的分号前加上 =0:就可以将一个虚函数变成纯虚函数,其中,=0只能出现在类内部的虚函数声明语句处.纯虚函数只用声明,而不用定义,其存在就是为了提供接口,含有纯虚函数的类是抽象基类 ...

  7. OOP2(虚函数/抽象基类/访问控制与继承)

    通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当 ...

  8. Python高级主题:Python ABC(抽象基类)

    #抽象类实例 作用统一规范接口,降低使用复杂度.import abcclass Animal(metaclass = abc.ABCMeta): ##只能被继承,不能实例化,实例化会报错 @abc.a ...

  9. PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)

    前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...

随机推荐

  1. TCP系列23—重传—13、RACK重传

    一.RACK概述 RACK(Recent ACKnowledgment)是一种新的基于时间的丢包探测算法,RACK的目的是取代传统的基于dupthresh门限的各种快速重传及其变种.前面介绍的各种基于 ...

  2. node必学的Hello World实现--服务器实现

    node是JavaScript运行在后端的一种实现.而后端语言,不管是php,java都需要一个服务器才能跑起来,node如是. node的服务器较php而言,少了单独安装服务器的步骤,node的服务 ...

  3. Windows Server 2012四大版本介绍

    今天刚好要尝试安装Windows Server 2012,在网上百度了下发现有4个版本,分别是: Datacenter数据中心版. Standard标准版. Essentials版. Foundati ...

  4. lucene 学习之基础篇

    一.什么是全文索引 全文检索首先将要查询的目标文档中的词提取出来,组册索引(类似书的目录),通过查询索引达到搜索目标文档的目的,这种先建立索引,再对索引进行搜索的过程就叫全文索引. 从图可以看出做全文 ...

  5. [计算机网络-应用层] P2P应用

    首先我们要先来区分一下下面的几种体系结构: CS:Client/Server 客户-服务器结构BS:Browser/Server  浏览器-服务器结构 P2P:Peer to Peer 对等结构 BS ...

  6. window 安装 nvm

    下载地址 https://github.com/coreybutler/nvm-windows/releases 设置淘宝镜像 nvm node_mirror https://npm.taobao.o ...

  7. error C2143: 语法错误 : 缺少“;”(在“类型”的前面)

    C编程老是遇到这个问题: 错误 error C2143: 语法错误 : 缺少“;”(在“类型”的前面) d:\kinectproject\ceshiglad\ceshiglad\shili.c ces ...

  8. 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  9. Python替换字符串中的反斜杠\

    s = 'cdp\nd' result = eval(repr(s).replace('\\', '@')) print(result) repr() 函数可以将字符串转换为python的原始字符串( ...

  10. [HNOI2010]合唱队 区间DP

    ---题面--- 题解: 偶然翻到这道题,,,就写了. 观察到一个数被插在哪里只受前一个数的影响,如果明确了前一个数是哪个,那么我们就可以确定大小关系,就可以知道当前这个数插在哪里,而上一个插入的数就 ...