第九章 分类和协议

第九章 分类和协议

9.1 分类
通过分类(category)可以以模块的方式向现有的类添加方法。 它提供了一种简单的方式, 用它可以将类

的定义模块化到相关方法的组或分类中。它还提供了扩展现有类定义的简便方式,并且不必访问类的源代 码,也无需创建子类。

对于 Fraction 类,除了将两个分数相加的 add:方法外,还想要拥有将两个分数相减、相乘和相除的方 法。

//**********************************************************************************************// // Fraction 类声明

#import<Foundation/Foundation.h> @interface Fraction : NSObject
{

int numerator;

int denominator; }

@property int numerator, deniminator; -(void) setTo:(int) n over: (int) d; -(Fraction *) add: (Fraction *) f; -(void) print;

// 声明分数的 加法函数

@end //*********************************************************************************************//

现在,从接口部分删除 add:方法,并将其添加到新分类,同时添加其他三种要实现的数学运算。看一

下新 MathOps 分类的接口部分。 //*********************************************************************************************//

#import<Foundation/Foundation.h>
#import "Fraction.h"
@interface Fraction (MathOps)
-(Fraction *) add: (Fraction *) f; // 加法函数

-(Fraction *) mul: (Fraction *) f;

-(Fraction *) sub: (Fraction *) f;

-(Fraction *) div: (Fraction *) f;

// 乘法函数 // 减法函数 // 除法函数

@end //*********************************************************************************************//

// #inport "Fraction.h" 这里既是分类接口部分的定义,也是对现有接口部分的扩展,所以必须包括原始接口部分 // @interface Fraction (MathOps) 告诉编译器正在为 Fraction 类定义新的分类,名称为 MathOps。

可以在一个实现文件中定义 Fraction.h 接口部分中的所有方法,以及 MathOps 分类中的所有方法。

也可以在单独的实现部分定义分类的方法。在这种情况下,这些方法的实现部分还必须找出方法所属 的分类。 与接口部分一样, 通过将分类名称括在类名称之后的圆括号中来确定方法所属的分类, 如下示:所

@implementation Fraction (MathOps) // code for category methods

... @end

关于分类的一些注意事项
A、 尽管分类可以访问原始类的实例变量, 但是它不能添加自身的任何变量。 如果需要添加量,变

可以考虑创建子类。
B、 分类可以重载该类中的另一个方法,但是通常认为这种做法不可取。因为,重载之后,再不

能访问原来的方法。
C、 可以拥有很多分类。
D、 和一般接口部分不同的是,不必实现分类中的所有方法。这对于程序扩展很有用,可以在该

分类中声明所有方法,然后在一段时间之后才实现它。
E、 通过使用分类添加新方法来扩展类不仅会影响这个类,同时也会影响它的所有子类。

9.2 协议 协议的声明类似于类接口的声明,有一点不同的是,协议没有父类,并且不能定义成员变量。下面的

例子演示了只有一个方法的协议的声明:

@protocol MyProtocol

- (void)myProtocolMethod; @end

协议是多个类共享的一个方法列表, 协议中列出的方法没有相应的实现。 如果一个类采用MyProtocol 协议,则必须实现名为 myProtocolMethod 的方法。

通过在@interface 行的一对尖括号<...>内列出协议名称,可以告知编译器你正在采用一个协议。这项 协议的名称放在类名和它的父类名称之后,如下所示:

@interface AddressBook: NSObject <myProtocol>

这说明, AddressBook 是父类为 AddressBook 的对象,并且它遵守 myProtocolMethod 协议。在 AddressBook 的实现部分,编译器期望找到定义的myProtocolMethod 方法。

如果采用多项协议,只需把它们都列在尖括号中,用逗号分开:
@interfaceAddressBook: NSObject<myProtocol,yourProtocol>
以上代码告知编译器 AddressBook 类采用 myProtocolMethod 和 yourProtocolMethod 协议。这次,编

译器将期望在 AddressBook 的实现部分看到为这些协议列出的所有方法的实现。

有关协议的注意事项:
A、如果一个类遵守某项协议,那么它的子类也遵守该协议。 B、协议不引用任何类,它是无类的(classless) 。任何类都可以遵守某项协议。 C、通过在类型名称之后的尖括号中添加协议名称,可以借助编译器的帮助来检查变量的一致性,如

下:

id <Drawing> currentObject;
这告知编译器 currentObject 将包含遵守 Drawing 协议的对象。 如果向currentObject 指派静态类型的对

象,这个对象不遵守 Drawing 协议,编译器将给出 warning。
再次提到 id 类型,如果向 currentObject 指派一个 id 变量,不会产生这条消息,因为编译器不知道存

储在 id 变量中的对象是否遵守 Drawing 协议。 D、如果这个变量保存的对象遵守多项协议,则可以列出多项协议,如下:

id <Drawing, Drawing 1> currentObject; E、定义一项协议时,可以扩展现有协议的定义。以下协议

@protocol Drawing3D <Drawing>
说明 Drawing3D 协议也采用了 Drawing 协议。因此采用 Drawing3D 协议的类都必须实现此协议列出

的方法,以及 Drawing 协议的方法。 F、分类也可以采用一项协议,如:

@interface Fraction (stuff) <NSCopying, NSCoding>
此处,Fraction 拥有一个分类 stuff,这个分类采用了 NSCopying 和 NSCoding 协议。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容