示例:分类、类的扩展
Fraction.h
#import <Foundation/Foundation.h> @interface Fraction : NSObject //@property指令让编译器自动为numerator、denominator生成getter、setter方法 @property int numerator, denominator; -(void) print; -(double) convertToNum; -(void) setTo: (int) n over: (int) d; -(void) set: (int) n : (int) d; -(void) reduce; +(Fraction *) allocF; +(int) count; @end
FractionMathOps.h
// Fraction.h 分类接口 // 按照惯例的命名方式为 类名分类名.h FractionMathOps.h // 也可以 类名+分类名.h Fraction+MathOps.h #import "Fraction.h" @interface Fraction (MathOps) -(Fraction *) add: (Fraction *) f; -(Fraction *) mul: (Fraction *) f; -(Fraction *) sub: (Fraction *) f; -(Fraction *) div: (Fraction *) f; @end
Fraction.m
#import "Fraction.h"
// 类的扩展:
// 在实现中声明一个未命名的分类接口,使reduce方法私有化(即外部无法访问).
// 1) 可以通过定义额外的实例变量和属性来扩展类,这在有命名的分类中是不允许的。
// 2) 未命名分类中声明的方法需要在主实现区域实现,而不是在分离的实现区域中实现。
// 3) 未命名分类中的方法都是私有的。
// 4) 分类可以覆盖该类中的另一个方法(通常认为这种做法是拙劣的设计习惯)
/*
@interface Fraction ()
-(void) reduce;
@end
*/
@implementation Fraction
@synthesize numerator, denominator;
// 用静态变量记录创建了多少个Fraction对象
// 静态变量不能被文件以外的代码访问
static int gCounter;
-(void) print
{
NSLog(@"%i/%i", numerator, denominator);
}
// 多个参数的方法
-(void) setTo: (int) n over: (int) d
{
numerator = n;
denominator = d;
}
-(double) convertToNum
{
if (denominator != 0)
return (double) numerator / denominator;
else
return NAN;
}
// 省略参数名的多个参数方法
// 注意,第一个参数名不能省
// 省略参数名不是一种好的编程风格,因为它使程序很难读懂并且很不直观,特别是参数很重要时。
-(void) set: (int) n : (int) d
{
numerator = n;
denominator = d;
}
// 约分
-(void) reduce
{
int u = numerator;
int v = denominator;
int temp;
while (v != 0) {
temp = u % v;
u = v;
v = temp;
}
numerator /= u;
denominator /= u;
}
+(Fraction *) allocF;
{
// 可以省略extern声明,写上也不会错
//extern int gCounter;
++gCounter;
return [Fraction alloc];
}
+(int) count
{
//extern int gCounter;
return gCounter;
}
@end
FractionMathOps.m
// Fraction.m 分类实现
#import "FractionMathOps.h"
@implementation Fraction (MathOps)
// 两个分数加相
-(Fraction *) add: (Fraction *) f
{
// 添加两个分数
// a/b+c/d=((a*d)+(b*c))/(b*d)
// 创建一个新对象来存储结果
Fraction *result = [[Fraction alloc] init];
result.numerator = self.numerator * f.denominator + self.denominator * f.numerator;
result.denominator = self.denominator * f.denominator;
[result reduce];
return result;
}
// 两个分数相乘
-(Fraction *) mul: (Fraction *) f
{
Fraction *result = [[Fraction alloc] init];
result.numerator = self.numerator * f.numerator ;
result.denominator = self.denominator * f.denominator;
[result reduce];
return result;
}
// 两个分数相减
-(Fraction *) sub: (Fraction *) f
{
Fraction *result = [[Fraction alloc] init];
result.numerator = self.numerator * f.denominator - self.denominator * f.numerator;
result.denominator = self.denominator * f.denominator;
[result reduce];
return result;
}
// 两个分数相除
-(Fraction *) div: (Fraction *) f
{
Fraction *result = [[Fraction alloc] init];
result.numerator = self.numerator * f.denominator;
result.denominator = self.denominator * f.numerator;
[result reduce];
return result;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "FractionMathOps.h"
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];
// 加
[a print]; NSLog(@" +"); [b print]; NSLog(@"-----");
result = [a add: b];
[result print];
NSLog(@"\n");
// 减
[a print]; NSLog(@" -"); [b print]; NSLog(@"-----");
result = [a sub: b];
[result print];
NSLog(@"\n");
// 乘
[a print]; NSLog(@" *"); [b print]; NSLog(@"-----");
result = [a mul: b];
[result print];
NSLog(@"\n");
// 除
[a print]; NSLog(@" /"); [b print]; NSLog(@"-----");
result = [a div: b];
[result print];
NSLog(@"\n");
}
return 0;
}