NSObject class和NSObject protocol的关系(抽象基类与协议)
【转载请注明出处】
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的关系(抽象基类与协议)的更多相关文章
- 6、面向对象以及winform的简单运用(抽象基类与接口)
抽象类与抽象方法 1.书写规范: 在类前面加上abstract关键字,就成为了抽象类:在一个方法前面加上abstract关键字,就成为了抽象方法(抽象方法不能有实现方法,直接在后面加分号) 例: ab ...
- C# 面向对象 , 抽象基类
抽象基类 关键字, abstract abstract class SSS { public void aaa() { } } 作为抽象基类, 只能在 继承关系 中 担任父类的角色,不能出现在其他地 ...
- thrift之TTransport类体系原理及源码详细解析1-类结构和抽象基类
本章主要介绍Thrift的传输层功能的实现,传输的方式多种多样,可以采用压缩.分帧等,而这些功能的实现都是相互独立,和上一章介绍的协议类实现方式比较雷同,还是先看看这部分的类关系图,如下: 由上面的类 ...
- guxh的python笔记七:抽象基类
1,鸭子类型和白鹅类型 1.1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__ ...
- 【Python】【元编程】【从协议到抽象基类】
"""class Vector2d: typecode = 'd' def __init__(self,x,y): self.__x = float(x) self.__ ...
- c++之——抽象基类
在一个虚函数的声明语句的分号前加上 =0:就可以将一个虚函数变成纯虚函数,其中,=0只能出现在类内部的虚函数声明语句处.纯虚函数只用声明,而不用定义,其存在就是为了提供接口,含有纯虚函数的类是抽象基类 ...
- OOP2(虚函数/抽象基类/访问控制与继承)
通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当 ...
- Python高级主题:Python ABC(抽象基类)
#抽象类实例 作用统一规范接口,降低使用复杂度.import abcclass Animal(metaclass = abc.ABCMeta): ##只能被继承,不能实例化,实例化会报错 @abc.a ...
- PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)
前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...
随机推荐
- JS 书籍拓展内容
一.面向对象
- 老生常谈-从输入url到页面展示到底发生了什么
来自:咸鱼老弟 - 博客园 链接:http://www.cnblogs.com/xianyulaodi/p/6547807.html
- 【Linux】- 文件基本属性
Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限.为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定. 在Linux中我们可 ...
- 【Linux】- Ubuntu守护进程supervisor
linux的守护进程类似于windows的服务.linux通过supervisor创建守护进程. 1.安装supervisor sudo apt-get install supervisor 安装成功 ...
- tomcat web页面管理应用配置
大部分时候,我们的tomcat服务器都不是部署在本机,那么怎么样不通过ftp/sftp方式来将war包部署到tomcat容器呢? tomcat有提供web页面管理应用的功能. 我们来看看怎么配置实现该 ...
- matlab中滤波函数
matlab自带滤波器函数小结(图像处理) 1 线性平滑滤波器 用MATLAB实现领域平均法抑制噪声程序: I=imread(' c4.jpg '); subplot(231) imshow(I) ...
- jquery计算器(改良版)
代码: <!Doctype html> <html> <meta charset="UTF-8"> <title>计算器</t ...
- 【问题解决】Project facet Java version 1.7 (或者1.8)is not supported.
在移植eclipse项目时,如果遇到 “Project facet Java version 1.7 is not supported.” 项目中的jdk1.7不支持.说明项目是其他版本jdk编译的, ...
- htm中的 src未指定具体路径的话 默认查找当前文件夹
htm中的 src未指定具体路径的话 默认查找当前文件夹
- 【bzoj4641】基因改造 特殊匹配条件的KMP
题目描述 如果两个长度相等的字符串,如果存在一种字符的一一映射,使得第一个字符串的所有字符经过映射后与第二个字符串相同,那么就称它们“匹配”.现在给出两个串,求第一个字符串所有长度等于第二个字符串的长 ...