Objective-C基础教程7
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2009年9月17日星期四
18
声明由他人来实现的接口
协议本质上就是一堆还未与任何类的实现代码关联的方法 的声明 比如,下面这些方法就可以用来组成一个协议: - (void)mouseDown:(NSEvent *)theEvent; - (void)mouseDragged:(NSEvent *)theEvent; - (void)mouseUp:(NSEvent *)theEvent; 任何想要对鼠标事件进行反馈的类都可以接受(adopt) 这个协议然后实现协议中的方法
2009年9月17日星期四
26
协议的声明
使用@protocol指令来声明一个协议: @protocol ProtocolName method declarations @end 例如: @protocol MyXMLSupport - initFromXMLRepresentation:(NSXMLElement *)XMLElement; @property (nonatomic, readonly) (NSXMLElement *)XMLRepresentation; @end
然而,如果你开发了一个对象,它要向一个你还没定义的类 的对象——有可能是你留给别人去写的类——发送消息,你 没有接受方的接口,从而无法继续 你需要另一种方式来声明你的消息中要使用的,还未被声明 的方法 协议可以很好地解决这种问题: 它告诉编译器你要使用的方法 它同时告诉别的实现者你需要他们在别的类中帮助你实现 的方法
2009年9月17日星期四
25
标准化协议 Formal Protocols
Objective-C提供了标准语法机制来声明协议 使用标准语法声明的协议成为标准化协议 标准化协议是得到了语言和运行环境的充分支持的 比如,编译器可以根据协议执行类型检查,运行环境 则允许对象通过自述性来报告自己是否确认了一个协 议
Objective-C 2.0编程语言
Lesson 7. 类的扩展
2009年9月17日星期四
1
扩展类的定义
Objective-C中提供了可以让你扩展类的定义的手段: 类目(Category):为已知的类增加新的方法 延展(Extension):通过在本类的定义里使用类目来声 明私有方法 协议(Protocol):声明一些方法,但是让别的类来实现 注意:这些手段只能增加类的方法,并不能用于增加实例 变量 要增加类的示例变量,只能通过定义子类来间接实现
13
定义延展
@interface MyObject : NSObject { NSNumber *number; } - (NSNumber *)number; @end @interface MyObject (Setter) } @end - (void)setNumber: (NSNumber *)newNumber; @end @implementation MyObject - (NSNumber *)number { return number;
24
声明由他人来实现的方法
当向assistant发送消息时,需要 检查它是否具备响应的能力: - (BOOL)doWork { ... if ( [assistant respondsToSelector:@selecto r(helpOut:)] ) { [assistant helpOut:self]; } 在写代码的时候,你不知道会 有什么类型的对象来注册成为 assistance,也不能包含具体类 的接口文件 所以你把helpOut:方法用协议 来声明,从而实现这一机制 return YES; } return NO;
2009年9月17日星期四
6
定义类目的实现
类目的实现定义中一般要包含它的接口文件 类目的接口文件一般用“类名+类目名.h”来命名 #import "ClassName+CategoryName.h" @implementation ClassName ( CategoryName ) // method definitions @end 你可以为一个类增加任意多个类目,但它们的类目名必须不 相同,它们包含的方法名也必须不相同
2009年9月17日星期四
16
协议 Protocols
协议是一种特殊的程序设计结构,用于声明专门被别 的类实现的方法 协议在以下场合非常有用: 声明需要由别的类实现的方法 声明未知类的接口 笼络一些互相之间没有继承关系的类的相似点
2009年9月17日星期四
17
声明由他人来实现的接口
类和类目的接口声明是严格与特定的类关联的,尤其 是由本类实现的方法的声明 协议声明的方法与任何特定的类都无关,它可以被任 何(还可能是很多)类来实现
2009年9月17日星期四
27
可选协议方法 Optional Protocol Methods
协议中的方法可以通过@optional 指令来标记为“可选”,即确认协 议的类可以不必实现的方法 相应地,也有@required指令来标 记“必需”方法 如果不做标记,默认是“必需”的 在Mac OSX 10.5中,不允许有可 选属性 @protocol MyProtocol - (void)requiredMethod; @optional - (void)anOptionalMethod; (void)anotherOptionalMethod; @required (void)anotherRequiredMethod; @end
2009年9月17日星期四
10
类目的错误用法
尽管语法上支持,但是不要在类目中复写已经存在的 方法,也不要复写其它类目中定义的方法 这样可能会导致: 向super传递的消息链断开 影响所有使用了该方法的代码的行为 尤其复写框架中的方法,是非常危险的
2009年9月17日星期四
11
对根类使用类目
根类也可以使用类目。向NSObject类增加的方法会被所 有的类继承 尽管这种用法非常便利,同时也非常危险 你在同时改变所有类,包括那些尚未定义的类的行为,而 且你可能无法想像你的改变将会带来的后果 在为根类定义类目时,注意两条: 不再可以向super发送消息了(已经不存在父类了) 根类中定义的实例方法可以被类对象执行!
2009年9月17日星期四
28
协议对象 Protocol Objects
就像类用类对象来代表一样,协议也有自己的特殊数 据类型来代表——协议对象 在很多方面,类跟协议很相似,它们都声明方法,在 运行时都由一个对象来表示——类使用类对象,协议 使用协议对象 像类对象一样,协议对象也是由源代码中的定义自动 被创建的
2009年9月17日星期四
2
类目 Categories
通过定义类目,你可以为已知的类增加新的方法—— 哪怕是那些你没有源代码的类 这是OC提供的一种强大的功能,使得你不用定义子类 就能扩展一个类的功能 使用类目,你还可以将你自己的类的定义分开放在不 同的源文件里
2009年9月17日星期四
3
定义类目
2009年9月17日星期四
20
声明由他人来实现的方法
如果你知道一个对象的类型,你便可以通过察看它的 类定义中的接口声明来得知它能够响应哪些消息 这种声明向使用者宣传了一个类可以调用的方法列表 协议也同样向使用者宣传了他可以调用的方法,并且 告知了实现者他应当实现的方法
2009年9月17日星期四
21
类目通过两部分代码来向原始类增加方法: 以一个类目名(category name)的名义在接口文件 中声明一些方法 以同样的类目名的名义在实现文件中定义这些方法 的实现
2009年9月17日星期四
4
定义类目
通过类目加入的方法会成为原始类的一部分。例如: 通过类目向NSArray增加方法,编译器会把这些方法加到 NSArray的定义里; 通过给NSArray定义子类来增加方法,则NSArray类的定义 里便不会包含这些方法 类目里定义的方法可以干任何原始类中方法能干的事,在运 行时,它们是平等对待的 类目里定义的方法也会被原始类的子类所继承,就跟原始类 的其它方法一样
2009年9月17日星期四
12
延展 Extensions
类的延展就像“匿名”的类目,延展中定义的方法在类本 身的@implementation代码区域中进行实现 类有时需要一些只为自己所见,所用的私有方法 这种私有方法可以通过延展的方式来声明 在延展中声明的方法可以没有实现,编译器不会警报
2009年9月17日星期四
2009年9月17日星期四
14
定义延展
当在定义延展的时候不提供类目名时,延展中定义的 方法既被视为“必须实现”的API 在这种情况下,如果方法缺少实现代码,则编译器会 报错 方法的实现必须出现在类主体的@implementation代码 块中
2009年9月17日星期四
15
定义延展
@interface MyObject : NSObject { NSNumber *number; } - (NSNumber *)number; @end @interface MyObject () - (void)setNumber:(NSNumber *)newNumber; @end } @end @implementation MyObject - (NSNumber *)number { return number; } - (void)setNumber:(NSNumber *)newNumber { number = newNumber;
声明由他人来实现的方法
对象之间的通信是两方面的:对象既可以发送消息, 也可以接收消息 如果你在开发中,在同一个工程里定义了消息的发送 方和接受方两个类,那么他们之间的通信便变得简 单: 发送方包含接受方的接口文件,调用接口文件中定义 的方法,向接受方传递消息
2009年9月17日星期四
22
声明由他人来实现的方法
2009年9月17日星期四
29
协议对象
在源代码中,想使用协议对象的时候,通过 @protocol(protocolName)指令来获得协议对象: Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport); 这是唯一的获取协议对象的手段 不同于类名,协议名单独使用时并不能代表协议对象本身 只有当协议: 被一个类接受了 或者在源代码某处被@protocol()命令引用了 运行环境才会自动生成协议的协议对象
2009年9月17日星期四
7
类目的用处
扩展别人实现的类 比如,你可以扩展Cocoa框架中的类,你在类目中增加 的方法会被子类所继承,而且在运行时跟其它的方法 没有什么两样
2009年9月17日星期四
8
类目的用处
作为子类的替代手段 不需要定义和使用一个子类,你可以通过类目直接向 已有的类里增加方法 跟定义子类一样,你不需要你所继承的类的源代码
2009年9月17日星期四
19
声明由他人来实现的接口
因为协议中让方法的声明与类和继承树完全脱离干系,所以它可 以用在一些类和类目无法发挥作用的地方 协议的实现可以在任何地方,但是它并不关心谁实现了它,而是 关心给定的类有没有实现它 一个类实现了协议中声明的方法称为“确认”(confirm)了这个协 议 这样继承树中不相干的类也可以因为确认了相同的协议而被归到 一起 尽管协议有着种种好处,它不像类的定义,O-C程序中并不是必 须要用到协议。协议与类目一样,都是可选(optional)语法
2009年9月17日星期四
9
类目的用处
把类的实现代码分布在不同的文件中 你可以把一个较大的类的方法成组地写到各个类目里,每一个类目 使用单独的文件 这样一来就能为开发过程提供以下好处: 一种简单的,给功能相近的方法分组的方式 易于多人合作开发同一个类 便于常用方法的移植 使得你可以为不同的程序设置同一个类的不同配置,而不用维 护很多版本的源代码
2009年9月17日星期四
23
声明由他人来实现的方法
例如:你声明了一个实例变量assistant,任何对象都可 以把自己注册成为assistant,来执行helpOut:方法 - setAssistant:(id)anObject { assistant = anObject; }
2009年9月17日星期四
2009年9月17日星期四
5
ቤተ መጻሕፍቲ ባይዱ
声明类目的接口
类目的接口声明与类的接口很相似——除了带有括号 中的类目名和没有父类名以外 #import "ClassName.h" @interface ClassName ( CategoryName ) // method declarations @end 类目的接口中不应当带有实例变量的声明