类别(category)
- 类别:类别是一种为现有的类添加新方法的方式。使用类别你可以为任何类添加新的方法,包括那些没有源代码的类。
- 通常会以“类名称+类别名称”的风格命名。这并不是硬性的规定,但却是一个好习惯。例如:NSString+NumberAsNSNumber.
类别的声明
#import <Foundation/Foundation.h> @interface NSString (NumberConvenience) -(NSNumber *) lenthAsNumber; @end
声明部分有几个非常有趣的特点。
- 类的名称后面是位于括号中的新名称,这意味着类别的名称叫做NumberConvenience,而且它是添加给NSString类的。只要保证类别名称唯一,你可以向一个类中添加任意数量的类别。
- 你可以指定想要添加类别的类(上述是NSString)和类别的名称(上述是NumberConvenience),还可以列出你要添加的方法,最后以@end结束。由于不能添加新的实例变量,因此这是不会像类声明那样包含实例变量声明的部分。
- 你可以在类别中添加属性,但是不能添加实例变量,而且属性必须是@dynami类型的。
类别的实现
#import "NSString+NumberConvenience.h" @implementation NSString (NumberConvenience) -(NSNumber *) lenthAsNumber { //获取客串的长度值 NSUInteger length =[self length]; return ([NSNumber numberWithUnsignedInt:length]); } @end
类别的实现与声明部分相似。
main函数的实现
#import <Foundation/Foundation.h> #import "NSString+NumberConvenience.h" int main(int argc, const char * argv[]) { @autoreleasepool { NSMutableDictionary *dict =[NSMutableDictionary dictionary]; [dict setObject:[@"hello" lenthAsNumber] forKey:@"hello"]; [dict setObject:[@"once time" lenthAsNumber] forKey:@"once time"]; NSLog(@"%@",dict); } return 0; }
通过以上步骤我们完成了让程序接收一系列的字符串,然后确定每个字符串的长度并存入到字典中。
这是有几点需要说明
- @"字符串"这种形式的字符串实际上就是地地道道的NSString对象,它们对消息的响应正如任何其他NSString对象一样。
- 任何NSString对象都能响应lengthAsNumber消息,包括字面量字符串、可变字符串、其他工具集某部分字符串、文件中加载的字符串、从因特网海量内容中撮的字符串,等等。
类扩展
类扩展的特点
- 它不需要名字
- 你可以在包含你的源代码的类(也就是你自己的类)中使用它。
- 你可以添加实例变量。
- 你可以将只读权限改成可读写的权限。
- 创建的数量不限
#import <Foundation/Foundation.h> @interface Things : NSObject @property (assign) NSInteger thing1; @property (readonly,assign) NSInteger thing2; -(void)resetAllValues; @end #import "Things.h" @interface Things () { NSInteger thing4; } @property (readwrite,assign) NSInteger thing2; @property (assign) NSInteger thing3; @end
这里没有继承的类,我们所做的基本上就是获取Things类,并通过私有属性和方法来扩展它。在这里我们修改了thing2读写权限,我们还添加了私有属性thing3,它只可以在这个类内部使用,另外还添加了thing4这个实例变量,它同样是私有的。
类别的优势与缺陷
优点:
- 将类的实现代码分散到多个不同的文件或框架中。
- 创建对私有方法的前向引用。
- 向对象添加非正式协议。
缺陷:
- 类别无法向类中添加新的实例变量。类别没有空间容纳实例变量。
- 名称冲突,也就是类别中的方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。你的类别方法将完全取代初始方法,导致初始方法不再可用。
类别和继承
- 为现有的类添加新的行为,通常也可以采用创建子类的方法(继承), 但是类别是有限制的,如现有的类你没有源代码,或者现有的类是类簇的形式存在。都无法添加新的行为。
所有评论(0)