Chapter 9 : 分类和协议
1. 分类(Category):
-> 作用:可以以模块的方式向现有的类添加方法,将类的定义模块化到相关方法的组或分类中。
-> 意义:提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无需创建子类。
2. 示例代码:
1 // Fraction类声明 2 // Fraction.h文件 3 4 #import <Foundation/Foundation.h> 5 6 @interface Fraction : NSObject 7 { 8 int numerator; 9 int denominator; 10 } 11 12 @property int numerator; 13 @property int denominator; 14 15 - (void)setTo:(int)n over:(int)d; 16 // 声明分数的加法方法 17 - (Fraction *)add:(Fraction *)f; 18 - (void)print; 19 20 @end
1 // 可将add:方法从@interface-@end中删除,将其添加到新分类,同时添加其他三种新的数学运算 2 3 #import <Foundation/Foundation.h> 4 #import "Fraction.h" 5 6 @interface Fraction (MathOps) 7 8 // 加法 9 - (Fraction *)add:(Fraction *)f; 10 // 乘法 11 - (Fraction *)mul:(Fraction *)f; 12 // 减法 13 - (Fraction *)sub:(Fraction *)f; 14 // 除法 15 - (Fraction *)div:(Fraction *)f; 16 17 @end
PS :
1 // 这里既是分类接口部分的定义,也是对现有接口部分的扩展,所以必须包括原始接口分 2 // #import "Fraction.h" 3 4 // 告诉编译器正在为Fraction类定义新的分类,名称为:MathOps 5 // @interface Fraction (MathOps)
分类方法的实现必须与方法所属的分类相对应:
1 @implementation Fraction (MathOps) 2 3 // Code for category methods 4 ... 5 6 @end
3. 分类(Category)注意事项:
-> 尽管分类(Category)可以访问原始类的实例变量,但它不能添加自身的任何变量,即只对添加方法有效,而添加变量则无效。
如果需要给原始类添加新的变量,则考虑使用创建子类的方法。
-> 分类(Category)可以重载原始类中的另一个方法,但是通常认为是这种做法不可取。因为,重载之后,再不能访问原来的方法。
-> 一个原始类可以拥有多个分类(Category)。
-> 和一般接口部分不同的是,不必实现分类(Category)的所有方法。这对程序扩展来说很有用,可以在该分类(Category)中声明所有方法,然后在一段时间这后才实现它。
-> 通过使用分类(Category)添加新方法来扩展不仅会影响这个类,同时也会影响它的所有子类。