所谓分类:即在不改变原来类内容的基础上,增加类的方法。
1. 分类的实现
下面为Fraction 类添加加减乘除四则算,
原始的Fraction类接口部分:
#import <Foundation/Foundation.h>
//定义Fraction类
@interface Fraction : NSObject
@property int numerator, denominator;
-(void)setTo:(int)n andOver:(int)d;
-(Fraction *) add: (Fraction *)f;
-(void) reduce;
-(double) convertToNum;
-(void) print;
@end
在原始类中添加分类的格式:
@interface Fraction (MathOps): 这个语句告诉编译器你为Fraction 声明了一个分类MathOps。
添加四则运算分类的代码如下:
#import <Foundation/Foundation.h>
#import "fraction.h"
//分类MathOps声明
@interface Fraction (MathOps)
-(Fraction *) add: (Fraction *) f;
-(Fraction *) mul: (Fraction *) f;
-(Fraction *) sub: (Fraction *) f;
-(Fraction *) div: (Fraction *) f;
@end
@implementation Fraction (MathOps)
-(Fraction *) add: (Fraction *) f
{
//两个分数相加
//a/b + c/d = ((a*d) + (c*b))/ (d*b)
Fraction *result = [[Fraction alloc] init];
result.numerator = (numerator * f.denominator) + (denominator * f.numerator);
result.denominator = denominator*f.denominator;
[result reduce];
return result;
}
-(Fraction *) mul: (Fraction *) f
{
//两个分数相减
//a/b + c/d = ((a*d) -(c*b))/ (d*b)
Fraction *result = [[Fraction alloc] init];
result.numerator = (numerator * f.denominator) - (denominator * f.numerator);
result.denominator = denominator*f.denominator;
[result reduce];
return result;
}
-(Fraction *) sub: (Fraction *) f
{
Fraction *result = [[Fraction alloc] init];
result.numerator = numerator * f.numerator;
result.denominator = denominator * f.denominator;
[result reduce];
return result;
}
-(Fraction *) div: (Fraction *) f
{
Fraction *result = [[Fraction alloc] init];
result.numerator = numerator * f.denominator;
result.denominator = denominator * f.numerator;
[result reduce];
return result;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Fraction *a = [[Fraction alloc] init];
Fraction *b = [[Fraction alloc] init];
Fraction *result;
[a setTo:1 over:3];
[b setTo:2 over:5];
result = [a add: b];
[result print];
result = [a mul: b];
[result print];
}
return 0;
}
对于分类文件的命名:一般来说分类的.h/.m 文件的名称由原类A 分类B的名称组合而成,可以是AB 或A+B。
使用时如果将分类放到主类定义的文件汇总,那么这个类的所有用户都将访问这个分类中的方法。如果不能直接修改原始的头文件,除了单独保存,没有其他选择
注意:
a. 分类只能增加方法,不能增加成员变量。
b. 分类方法实现中可以访问原类中声明的成员变量。
c. 方法调用的优先级:分类(最后参与编译的分类优先)--->原类--->父类。
d.分类可以重载该类的另一个方法,但是通常认为这种做法是卑劣的设计习惯。第一:重载一个方法后,再也不能访问原来的方法,因此,必须小心将被重载方法中的所有功能复制到替换方法中,如果确实需要重载方法,可以考虑常见子类,如果在子类中重载方法,仍然可以通过想super发送消息类来引用父类的方法。因此不必了解重载方法的内容就能够调用父类的方法,并向子类的方法添加自己的功能。