自定义现有的类 - Customizing Existing Classes

上传人:野鹰 文档编号:2668125 上传时间:2017-07-26 格式:PDF 页数:7 大小:199.65KB
返回 下载 相关 举报
自定义现有的类 - Customizing Existing Classes_第1页
第1页 / 共7页
自定义现有的类 - Customizing Existing Classes_第2页
第2页 / 共7页
自定义现有的类 - Customizing Existing Classes_第3页
第3页 / 共7页
自定义现有的类 - Customizing Existing Classes_第4页
第4页 / 共7页
自定义现有的类 - Customizing Existing Classes_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《自定义现有的类 - Customizing Existing Classes》由会员分享,可在线阅读,更多相关《自定义现有的类 - Customizing Existing Classes(7页珍藏版)》请在金锄头文库上搜索。

1、定义现有的类 - Customizing Existing Classes定义现有的类 - Customizing Existing Classes每个对象都应该有明确的任务,如为具体信息建模,显可视化内容或者控制信息流。 另外正如你所知道的,个类的接定义了其利个对象来帮助它完成任务的连接式。有时你会发现你希望通过添加某些法来扩展现有的类,但这只在某些情况下是有的。 举个例,你发现你的应程序经常需要在个可视化界显些字符串信息。 那么除了在每次你需要显字符串时创造个字符串绘图对象来使外,给NSString 类本赋予可以在屏幕上绘制字符的能会更有意义。在这种情况下,对原始的、主要的类的接增加功能法

2、并不总是可的。 因为在多数应字符串对象的程序中,绘图能并不总是被要求的。 例如,在 NSString 类中,你不能修改原来的接或是继承,因为它是个框架类。此外,上述法对现有类的类也是没有意义的,因为你可能希望你的绘图能不仅对原始的 NSString 类有效,也有对该类类有效,如 NSMutableString 类。 另外虽然NSString 类在 OS X 和 iOS 两个操作系统内均可使,但相关绘图能的代码在每个操作系统内是不同的,所以你需要在每个操作系统内使不同的类。然,Objective-C 允许你通过 categories 和类扩展来对已有的类中添加你定义的法。使 Categories

3、 对现有的类添加法如果你需要添加法到现有类,是为了添加某些功能使你的应程序在完成某些任务时更容易,那么使 category 是最便的法。使 interface 关键字来声明个 category ,就像标准的 Objective-C 类的描述样,但并不表这个 category 从任何个类继承。 另外它指定 category 的名称在括号内,像这样:interface ClassName (CategoryName)end个 category 可以声明任何类,即使是在没有原始代码的类(如标准的 Cocoa 或Cocoa Touch 的类)。 你在 category 中声明的任何法都可以被原始类和任

4、何原始类的类所实例化。 同时在运时,你在 category 添加的法和由原始类实现的法之间是没有区别的。请考虑在之前章节提过的 XYZPerson 类,它具有个的姓和名字的属性。 如果你在写个记录的应程序,你会发现你经常需要显个按姓排列的名单,像这样:Appleseed, JohnDoe, JaneSmith, BobWarwick, Kate如果你不想在每次显这个列表的时候再编写代码来成适当的 lastName ,firstName 字符串, 那么你可以向 XYZPerson 类如下所添加个 category :#import XYZPerson.hinterface XYZPerson (

5、XYZPersonNameDisplayAdditions)- (NSString *)lastNameFirstNameString;end在此例中,名为 XYZPersonNameDisplayAdditions 的 category 声明了个额外的法以返回必需的字符串。个 category 通常是在单独的头件中声明的,并在单独的源代码件被实现。 例如在 XYZPerson 类中,你可能会声明个 category 在XYZPerson+XYZPersonNameDisplayAdditions.h 的头件中。虽然 category 添加的任何法都可于此类及其类的所有实例中,但你仍需要在任何

6、要使添加的法的源代码件中导含有 category 的头件,否则你可能会遇到编译器警告和错误。Category 的实现如下所:#import XYZPerson+XYZPersonNameDisplayAdditions.himplementation XYZPerson (XYZPersonNameDisplayAdditions)- (NSString *)lastNameFirstNameString return NSString stringWithFormat:%, %, self.lastName, self.firstName;end旦你已经声明个 category 并继承这些法

7、,你可以在此类的任何实例中使这些法,就好像他们是原始类接的部分样:#import XYZPerson+XYZPersonNameDisplayAdditions.himplementation SomeObject- (void)someMethod XYZPerson *person = XYZPerson alloc initWithFirstName:JohnlastName:Doe;XYZShoutingPerson *shoutingPerson =XYZShoutingPerson alloc initWithFirstName:MonicalastName:Robinson;NS

8、Log(The two people are % and %,person lastNameFirstNameString, shoutingPerson lastNameFirstNameString);end除了可以向现有的类添加法,你还可以使 categories 把多功能的源代码件中个复杂的类拆分。 例如,你把个定义户界元素的绘图代码放在个单独的category 中,来执些其余的功能如何计算、 颜和渐变等,这就是个特别复杂的类的例。 另外你可以给类别的法提供不同的实现,具体取决于你正在写个OS X 还是 iOS 的应程序。Categories 可于声明类法或成员法,但并通常适合声明附加

9、属性。 在个category 的接中包含属性声明时编译器不会报错,但是不能在个 category 中声明个附加的成员变量。 这意味着,编译器不会为该属性合成任何成员变量,也不合成任何属性访问法。 在类的实现过程中,你可以编写你的访问法,但是你不能来跟踪该属性的值,除原始类中已有了该成员变量。添加个传统属性的唯式也就是从现有类持个新的成员变量是使类扩展,如 Class Extensions Extend the Internal Implementation。注: Cocoa 和 Cocoa Touch 包括了量的主要框架类的 categories。这章的导中提到的字符串绘图功能事实上已经由 O

10、S X 中名为NSStringDrawing 的 category 提供给 NSString 类了,其中包括drawAtPoint:withAttributes: 和 drawInRect:withAttributes: 法。 对于 iOS,UIStringDrawing category 包括 drawAtPoint: withFont 法和drawInRect: withFont 法。避免 categories 法名冲突因为在个 category 中声明的法已经添加到现有的类中,所以你需要常有关法名的定义问题。如果在个 category 中声明的法和在原始类中的法或该类(甚是在个类)的其他

11、 category 中的法名称相同,在运时,编译哪种法的指令将被认为是未定义的。 如果你正在使你的类的 categories ,使的 categories 会将法添加到标准的 Cocoa 或 Cocoa Touch 类时导致问题。例如当你的应程序与远程 web 服务交互时,可能需要种使 Base64 编码技术来编码字符串的法。 因此你可以通过在 NSString 类上定义个 category ,添加个称为 base64EncodedString 的实例法以返回个 Base64 编码的字符串。但是如果你链接到另个框架,恰巧也在 NSString 类的定义 category 中包括了此法 也称为

12、base64EncodedString 时 ,那么将会出现问题。 在运时,只有个法会“赢”,并添加到 NSString 类中,另个则成为未定义不起作。如果你添加法到 Cocoa 或 Cocoa Touch 类和之后版本的原始类中,那么可能会出现另个问题。例如 NSSortDescriptor 类,它描述了个对象的集合应该是如何排序的,包含有aninitWithKey: accending 初始化法。但并没有在早期的 OS X 和 iOS 版本下提供相应的类法。按照约定,类法应该叫做 sortDescriptorWithKey: accending ,所以为便起见你要选择添加个 category

13、 到 NSSortDescriptor 类上来提供此法。 这是在旧版本的OS X 和 iOS 下操作的,但随着 Mac OS X 10.6 版本和 iOS 4.0 的发布,个叫sortDescriptorWithKey 的法添加到原始的 NSSortDescriptor 类中,意味着在这些或更版本操作系统上运你的应程序时,你不再会有命名冲突的问题。为了避免未定义的为,最佳的做法是给框架类 categories 中的法名添加个前缀,就像你向你的类的名称添加个前缀样。你可以选择使和你的类的前缀相同的三个字母,但要写以遵循法命名的规则,然后在法名称的其余部分之间个下划线连接。对于 NSSortDes

14、criptor 的例,你的 category 应该看起来像这样:interface NSSortDescriptor (XYZAdditions)(id)xyz_sortDescriptorWithKey:(NSString *)key ascending:(BOOL)ascending;end这意味着你可以肯定你的法在运时可以使。歧义将会被删除,你的代码现在看起来像这样:NSSortDescriptor *descriptor =NSSortDescriptor xyz_sortDescriptorWithKey:name ascending:YES; extension 来实现类的扩展类扩

15、展与 category 有相似性,但在编译时它只能被添加到已有源代码的类中(该类扩展和该类同时被编译)。声明个类扩展的法在原始类 implementation 块中,所以你不能,举个例,在框架类上声明个类扩展,如 Cocoa 或 Cocoa Touch 的 NSString 类。于声明类扩展的语法类似于个 category 声明的语法,看起来像这样:interface ClassName ()end因为没有在括号内给定名称,所以类扩展通常称为匿名类。不像般的 categories ,类扩展可以向类中添加其的属性和成员变量。如果你在类扩展中声明个属性,要像这样:interface XYZPerson ()property NSObject *extraProperty;end编译器会动合成相关的访问法,以及个成员变量,继承到主要的类。如果你在个类扩展中添加任何法,这些必须在主要类中继承。也可以使个类扩展来添加定义的成员变量。这些变量在类扩展接中的括号内声明:interface XYZPerson () id _

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号