Objective-C学习笔记八:类的定义二

     我们继续来扩展分数类Fraction,两个分数相加,再不考虑它们是不是最简分数的情况下,有下面的公式成立:a/b+c/d=(ad+bc)/bd,那么我们在Fraction类中添加一个add方法,代码如下:
C代码   收藏代码
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Fraction : NSObject  
  4.   
  5. @property int numerator,denominator;  
  6.   
  7. -(void) print;  
  8. -(double) convertToNum;  
  9. -(void) setTo:(int) n over: (int) d;  
  10. -(void) add:(Fraction *) f;  
  11.   
  12. @end  

    注意这个add方法的定义,参数类型是指针类型的Fraction,那么编写函数实现:
C代码   收藏代码
  1. #import "Fraction.h"  
  2.   
  3. @implementation Fraction  
  4.   
  5. @synthesize numerator,denominator;  
  6.   
  7. -(void) print  
  8. {  
  9.     NSLog(@"%i/%i",numerator,denominator);  
  10. }  
  11.   
  12. -(double) convertToNum  
  13. {  
  14.     if(denominator!=0){  
  15.         return (double)numerator/denominator;  
  16.     }else{  
  17.         return NAN;  
  18.     }  
  19. }  
  20.   
  21. -(void) setTo:(int)n over:(int)d  
  22. {  
  23.     numerator=n;  
  24.     denominator=d;  
  25. }  
  26.   
  27. -(void) add:(Fraction *)f  
  28. {  
  29.     numerator=numerator*f.denominator+denominator*f.numerator;  
  30.     denominator=denominator*f.denominator;  
  31. }  
  32.   
  33. @end  

    这个实现方法内的计算过程就是数学公式的程序化。之后修改主函数,代码如下:
C代码   收藏代码
  1. #import "Fraction.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.     @autoreleasepool {  
  6.         Fraction *fractionA = [Fraction new];  
  7.         Fraction *fractionB = [Fraction new];  
  8.           
  9.         [fractionA setTo:10 over:406];  
  10.         [fractionB setTo:23 over:901];  
  11.           
  12.         [fractionA print];  
  13.         [fractionB print];  
  14.           
  15.         [fractionA add:fractionB];  
  16.           
  17.         [fractionA print];  
  18.     }  
  19.     return 0;  
  20. }  

    编译运行,我们得到如下结果:



    当然这里我们没有对分数进行化简。
    当有方法定义的时候,就会涉及到局部变量的概念。在方法内部定义的变量就是局部变量,局部变量没有初始值,需要人为进行赋值操作。这些变量的作用域就是这个方法调用的生命周期,当方法返回结果后,本次局部变量就都消失了。也就是每次方法调用时,重新生成局部变量,赋值,使用,返回结果后它们就消失了。我们继续来编写分数化简的方法,其中使用到了局部变量,代码如下:
C代码   收藏代码
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Fraction : NSObject  
  4.   
  5. @property int numerator,denominator;  
  6.   
  7. -(void) print;  
  8. -(double) convertToNum;  
  9. -(void) setTo:(int) n over: (int) d;  
  10. -(void) add:(Fraction *) f;  
  11. -(void) reduce;  
  12.   
  13. @end  

    我们加入了reduce方法,数学概念中,分数的化简就是找出分子和分母的最大公约数,然后分子分母同时除以这个最大公约数,就得到了最简分数。我们之前用到过求最大公约数的示例,那么这里我们直接使用,实现代码中这样来写:
C代码   收藏代码
  1. -(void) reduce  
  2. {  
  3.     int n=numerator;  
  4.     int d=denominator;  
  5.     int temp;  
  6.       
  7.     while (d!=0) {  
  8.         temp=n%d;  
  9.         n=d;  
  10.         d=temp;  
  11.     }  
  12.       
  13.     numerator/=n;  
  14.     denominator/=n;  
  15. }  

    之后修改主函数:
C代码   收藏代码
  1. #import "Fraction.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.     @autoreleasepool {  
  6.         Fraction *fractionA = [Fraction new];  
  7.         Fraction *fractionB = [Fraction new];  
  8.           
  9.         [fractionA setTo:10 over:406];  
  10.         [fractionB setTo:23 over:901];  
  11.           
  12.         [fractionA print];  
  13.         [fractionB print];  
  14.           
  15.         [fractionA add:fractionB];  
  16.           
  17.         [fractionA reduce];  
  18.           
  19.         [fractionA print];  
  20.     }  
  21.     return 0;  
  22. }  

    编译运行后,我们就得到如下的结果了:



    扩展我们说过的局部变量的含义,方法的参数也是局部变量,比如对于方法 -(double) add: (double) x,那么调用这个方法时可以是这样的 [data add: val]。在方法中我们使用的是x变量,而传入的是val变量,val变量赋值给x后,val本身没有变化,而作为局部变量的x发生的所有变化都与val无关。
    而上面我们传入对象参数时,则可以在方法中修改其实例变量的值,这是因为我们传递的是数据存储的引用位置,所以才能在方法中修改其中的值。
    关键字static可以修饰变量,当static修饰局部变量时,那么这个值可以保存多次调用该方法所得到的值。而且它会在程序开始执行时初始化一次,因此需要对其先赋好值。如果static修饰的不是局部变量,那么所有的方法就都可以访问它们了。
    对于分数化简的方法,我们继续探究。如何在add方法内调用reduce方法,那么在主函数中就不必再次调用该方法,而且分数做完加法后自动完成化简也是更佳的做法。那么问题就是如何在一个方法内调用本类定义的其它方法,关键字self就是完成这个功能的。self关键字用来指明对象是该方法的调用者,比如 [self reduce]。上述方法就可以改为:
C代码   收藏代码
  1. -(void) add:(Fraction *)f  
  2. {  
  3.     numerator=numerator*f.denominator+denominator*f.numerator;  
  4.     denominator=denominator*f.denominator;  
  5.     [self reduce];  
  6. }  

    结合上面的代码,分数化简后返回化简后的分数,此时如果我们想返回这个分数对象,又改怎么做呢?这就是方法返回对象的问题,上述代码继续扩展如下:
C代码   收藏代码
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Fraction : NSObject  
  4.   
  5. @property int numerator,denominator;  
  6.   
  7. -(void) print;  
  8. -(double) convertToNum;  
  9. -(void) setTo:(int) n over: (int) d;  
  10. -(void) add:(Fraction *) f;  
  11. -(Fraction *)add2:(Fraction *)f;  
  12. -(void) reduce;  
  13.   
  14. @end  

    我们加入了新方法的定义,防止重名方法,那么实现如下:
C代码   收藏代码
  1. -(Fraction *)add2:(Fraction *)f  
  2. {  
  3.     Fraction *result=[Fraction new];  
  4.     result.numerator=numerator*f.denominator+denominator*f.numerator;  
  5.     result.denominator=denominator*f.denominator;  
  6.     [result reduce];  
  7.     return result;  
  8. }  

    主函数修改如下:
C代码   收藏代码
  1. #import "Fraction.h"  
  2.   
  3. int main(int argc, const char * argv[])  
  4. {  
  5.     @autoreleasepool {  
  6.         Fraction *fractionA = [Fraction new];  
  7.         Fraction *fractionB = [Fraction new];  
  8.         Fraction *resultFraction;  
  9.           
  10.         [fractionA setTo:10 over:406];  
  11.         [fractionB setTo:23 over:901];  
  12.           
  13.         [fractionA print];  
  14.         [fractionB print];  
  15.           
  16.         resultFraction=[fractionA add2:fractionB];  
  17.           
  18.         [resultFraction print];  
  19.   
  20.     }  
  21.     return 0;  
  22. }  

    编译运行后,我们得到如下结果:



    到目前为止,我们已经编写了一个功能相对完整的类Fraction,对于此时的头文件,完全可以作为我们处理分数的方法库,并且可以将我们编写的程序提供给他人使用。如果要添加新的方法而不修改已有方法,可以通过定义扩展类来实现该目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒙奇·D·路飞-

感谢老板您就是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值