在Objective-C语言中, 类别、类扩展(也称为匿名类别)以及协议是Objective-C 语言级别支持的模式,用来实现对类进行功能扩展。

一、类别--用来增加方法到已存在类

声明一个类别的语法如下:

@interface ClassName (CategoryName)

@end

Objective-C 的标准的类声明,也使用@interface 关键字。但类别与类声明区别的是在括号中声明了一个类别名字。

类别能为任何类添加类别,包括不知道源代码的类(例如标准的Cocoa Touch 类等)。

已声明类别的类,类及其子类的所有实例都可以使用声明在类别中的方法,在运行时,通过类别为类添加的方法与类本身的方法没有任何区别。

类别也通常在头文件中进行声明,在分离的源文件中进行类别方法的实现。

为了使用为类添加的类别,需要在使用的地方输入声明类别的头文件。

类别可以作为一种设计模式使用,用来使用类别把一个实现复杂的类分离为几个实现文件。也可以为不同的平台提供不同的类别实现方法。

类别用来声明实例方法或类方法,但不适合声明额外的属性。

在一个类别接口中声明一个属性是有效的,但在类别中声明一个额外的实例变量是不可能的,这意味者编译器不能够生成任何实例变量,也不能够生成任何属性存取方法。
但你能够在类别实现中实现自己的属性存取方法,但你不能够保持和跟踪一个属性值,除非它已经在原先的类中存储。

另外需要注意的是类别中定义的方法名字不能与该类已有的方法或为该类(或其超类)定义的其它类别中的方法冲突。

为已存在类添加带有实例变量的属性的仅有的方法是使用类扩展。

二、类扩展--用来扩展一个类的内部实现

类扩展功能上与类别类似,用来扩展一个类的功能,与类别不同的是,类扩展中能为一个类增加属性和实例变量。另外类扩展仅能在一个有源码的类中使用,用来为其添加功能。使用类扩展通常用来实现和扩展类的私有信息(包括私有属性和方法)。

声明一个类扩展的语法与类别的语法相似,但括号中名字为空,因此类扩展也被称为匿名类别。如下所示:

@interface ClassName ()

@end

类扩展中声明的方法要在原先类的@implementation块中加以实现。

如果在一个类扩展中声明一个属性,编译器自动为其生成相对应的存取方法和一个实例变量。如果在一个类扩展中增加任意方法,它们也必须在类的实现中加以实现。

在一个类扩展中添加定制的实例变量也是可能的。

三、协议

在Objective-C中,每个类都都对外提供自己的接口,类包括接口声明和类实现。而没有像其它语言(如java)那样,接口与类定义是独立的,一个类可以实现多个接口。

但在Objective-C中协议可以起到类似的作用,协议用来声明与任何特定的类独立的方法,如果一个类声明符合某种协议,则其实现中必须实现协议中声明的方法,但与其它语言接口定义不同的是在协议中不仅能声明对象方法,还能声明类方法以及属性。

定义一个协议的语法如下:

@protocol ProtocolName

// list of methods and properties

@end

Objective-C 使用三角括号指示一个属性或类符合一种协议。

默认情况下在一个协议中声明的方法都是必须方法,任何符合该协议的类必须实现这些方法。

在协议中也可以使用@optional关键字规定可选方法。遵从包括可选方法的协议的类可以根据需要实现可选方法或不实现。

@protocol XYZPieChartViewDataSource

- (NSUInteger)numberOfSegments;

- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;

@optional

- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;

- (BOOL)shouldExplodeSegmentAtIndex:(NSUInteger)segmentIndex;

@required

- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;

@end

在以上协议声明中的titleForSegmentAtIndex:和shouldExplodeSegmentAtIndex:方法标记为是可选方法。

@optional关键字指示其下面声明的方法都是可选方法,直到协议定义结束或碰到另外的@required指令。

如果在一个协议中标记一个方法为可选,你必须在试图调用它之前检查是否一个对象实现了该方法。

使用respondsToSelector: 方法使用一个@selector指令引用一个方法的标识(方法名)来检查该方法是否实现。如下所示:

NSString *thisSegmentTitle;

if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {

thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];

}

也可以规定一个协议符合另外的协议,语法如下:

@protocol MyProtocol <NSObject>

...

@end

声明一个类符合一个协议的语法如下:

@interface MyClass : NSObject <MyProtocol>

...

@end

与其它语言一个类可以实现多个接口相同,在Objective-C也可以声明一个类符合多个协议,语法如下:

@interface MyClass : NSObject <MyProtocol, AnotherProtocol, YetAnotherProtocol>

...

@end

但如果出现这种情况,意味着你的类过于复杂,需要重构,分离相关的行为到多个较小的类,每一个类定义清楚的责任。

Objective-C的面向对象特性(二)的更多相关文章

  1. TypeScript入门知识五(面向对象特性二)

    1.泛型(generic) 参数化的类型,一般用来限制集合的内容 class Person { constructor(private name: string) { } work() { }}var ...

  2. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  3. Python 基础 面向对象之二 三大特性

    Python 基础 面向对象之二 三大特性 上一篇主要介绍了Python中,面向对象的类和对象的定义及实例的简单应用,本篇继续接着上篇来谈,在这一篇中我们重点要谈及的内容有:Python 类的成员.成 ...

  4. Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  5. javascript进阶——面向对象特性

    面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...

  6. .NET面向对象特性之封装

    .NET面向对象特性之封装 面向对象的基本内容由:类.对象.属性.方法.字段构成. 面向对象的三大特性:继承.多态.封装. 关于面向对象的特性很多人都把目光转向了继承.多态和接口,却很少有人提及过封装 ...

  7. .NET面向对象特性之多态

    .NET面向对象特性之多态 前言 上一篇总结了面向对象三大特性之一的继承,再接再厉,这一章继续总结多态.同时把继承中涉及到多态的内容进一步补充扩展.可以说“继承”是多态的根基.但继承主要关注的是“共通 ...

  8. .NET面向对象特性之“继承”

    整体简介 1.理解继承——继承关系图 2.实现继承与接口多继承 3.new. virtual.override方法 4.抽象方法和抽象类的继承 5.继承的本质 6.继承的复用性.扩展性和安全性 7.多 ...

  9. TypeScript -- 面向对象特性

    .class关键字和类名就可以定义一个类 . 类的访问控制符--有三个,.] = ] = ] = ;.声明参数 .用接口声明方法 .理解模块--一个文件就是一个模块,就是这么个意思 ,不用想的多么高大 ...

  10. 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态

    一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...

随机推荐

  1. 信用卡3D验证相关资料

    3D 验证服务,是银行与VISA .MASTERCARD国际组织联合推出的为保障银行维萨及万事达信用卡持卡客户网上交易安全,防范网上伪冒交易的一项信用卡网上支付安全验证服务( 维萨卡使用的验证服务叫& ...

  2. Spring配置优化_构造器注入+自动装配

    2014-05-16 09:01:08上课内容: 依赖注入的第二种注入方式:构造器注入 创建带参数的构造方法,参数类型为注入类的类型 项目要先添加Spring支持: package com; publ ...

  3. velocity map list 数组操作

    Velocity生成模板的时候,经常需要使用到map.list对象,然后遍历输出对象的属性值.当你需要遍历的时候记录遍历的步长的时候,可以使用$velocityCount内置变量进行输出.下面demo ...

  4. 5.3、Android Studio录像

    Android Monitor允许你从设备中录制一段MP4格式的视频,最长允许3分钟. 录制视频 在硬件设备中录制视频: 1. 打开一个项目 2. 在设备中运行应用 3. 显示Android Moni ...

  5. Qzone React Native改造

    Android Qzone 6.1版本在情侣空间涉水React Native,以动态插件方式将情侣空间进行React Natived的改造.在情侣空间基础上,Android Qzone 6.2版本以融 ...

  6. React实现动画效果

    流畅.有意义的动画对于移动应用用户体验来说是非常必要的.和React Native的其他部分一样,动画API也还在积极开发中,不过我们已经可以联合使用两个互补的系统:用于全局的布局动画LayoutAn ...

  7. 开源项目——小Q聊天机器人V1.5

    小Q聊天机器人V1.0 http://blog.csdn.net/baiyuliang2013/article/details/51386281 小Q聊天机器人V1.1 http://blog.csd ...

  8. tomcat如何路由映射网址

    对于web容器来说,根据请求客户端路径路由到对应的资源属于其核心功能,假设用户在自己电脑上使用浏览器输入网址http://www.test.com/test/index.jsp,报文通过互联网网络到达 ...

  9. Mysql大量插入数据时SQL语句的优化

    1) 对于Myisam类型的表,可以通过以下方式快速的导入大量的数据.     ALTER TABLE tblname DISABLE KEYS;    loading the data    ALT ...

  10. qualcomm memory dump 抓取方法

    Memory dump是系统出现crash时常用的分析故障原因的方法,qualcomm 各子系统运行时,为方便debug,都会开辟ram log和debug variable用于保存各系统运行信息及健 ...