@interface Fraction : NSObject {
int numerator;
int denominator;
}
@property int numerator, denominator;
-(void) print;
-(double) convertToNum;
-(void) setTo: (int) n over: (int) d;
-(Fraction *) add: (Fraction *) f;
-(void) reduce;
-(Fraction *) initWithFract: (int) n over: (int) d;
@end
Fraction.m的內容為:
#import "Fraction.h"
@implementation Fraction
@synthesize numerator, denominator;
-(void) print{
NSLog(@"%i/%i",numerator,denominator);
}
-(double) convertToNum{
if (denominator!=0)
return (double) numerator/denominator;
else
return 1.0;
}
-(void) setTo: (int) n over: (int) d{
numerator=n;
denominator=d;
}
-(Fraction *) add: (Fraction *) f{
Fraction *result=[[Fraction alloc] init];
[result setTo: numerator * f.denominator + denominator * f.numerator
over: denominator * f.denominator];
[result reduce];
[result autorelease];
return result;
}
-(void) reduce{
int u = numerator;
int v = denominator;
int temp;
while (v !=0) {
temp = u % v;
u = v;
v = temp;
}
if(denominator/u<0){
numerator=-numerator/u;
denominator=-denominator/u;
}
else{
numerator = numerator/u;
denominator=denominator/u;
}
}
-(Fraction *) initWithFract: (int) n over: (int) d{
self=[super init];
if(self)
[self setTo:n over:d];
return self;
}
@end
主程式test.m
#import <Foundation/Foundation.h>
#import "Fraction.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *a=[Fraction alloc];
Fraction *b=[Fraction alloc];
Fraction *result;
[a initWithFract:1 over:2];
[b initWithFract:1 over:4];
[a print];
NSLog(@" +");
[b print];
NSLog(@"-----");
result=[a add:b];
[result print];
[result release];
[a release];
[b release];
[pool drain];
return 0;
}
編譯執行的結果為:
1/2
+
1/4
------
3/4
在這個例子中,我增加了幾個methods:
add: 把兩個分式相加,形成新的分式。
setTo: over: 也是設定分式的值,但這個method一次傳遞二個參數。
covertToNum 得到分式的值。
reduce 這個method是約分分式,如果是6/8,可轉換成3/4。
在這個例子中,我要主要介紹的重點:自動產生setter nad getter methods,以及 super 和 self 這兩個詞在implementation 時的用法。
自動產生setter & getter methods,這是Objective-C 2.0才有的功能:
在Fraction class的宣告完instance variables後,再宣告methods時,這時使用key word "@property", 變數 的 資料型態 和 變數名稱後,最後以分號結尾,如本例:
@property int numerator, denominator;
這等於宣告了四個methods:
// numerator setter and getter:
-(void) setNumerator: (int) n;
-(int) numerator;
// denominator setter and getter :
-(void) setDenominator: (int) d;
-(int) denominator;
而在@implementation時,用Key Word "@synthesize" 變數名稱後再加上分號結束句子,如本例的
@synthesize numerator, denominator;
這個句法,等於implement 上述的setNumerator, numerator, setDenominator, denominator 這四個methods 了。
存取物件的instance variables, 如果物件class已有了setter and getter methods,則可以用 "."來直接存取其值:
如 a 是Fraction class的物件,則
a.numerator=3;
等同於
[a setNumerator: 3];
super 及 self 的用法
這兩個詞是用在 methods的 實行(implemented)中,super 代表其 superclass,而self代表 本身class。
物件導向程式設計有一個重點是遺傳或者繼承(inheritance )的特性。長輩(parent class or superclass)所定義的methods,子輩(subclass of parent class)則自動有執行這些methods的能力。本例中,Fraction class是NSObject class的 subclass,所以NSObject class所定義的methods,也可被Fraction class的物件使用。
下表來說明super和 self的差別:
| @interface Fraction : NSObject |
| NSObject class methods | init, release, alloc, autorelease, print(如果有的話)... | | Fraction class methods | reduce, add:, print,.... |
implemented methods using superclass methods | [super init], [super print]..... | implemented methods using Fraction class methods | [self reduce], .... | 如同名 method,如本例的print,[super print]是執行NSObject Class 定義的 print method,而 [self print]則是執行Fraction class定義的 print method,這二者不要弄錯了。 |
這兩個詞只有implementation是才會使用到,如本例Fraction class的 print method,可以改寫成:-(void) print{
NSLog(@"%i/%i", self.numerator, self.denominator);
//或者 NSLog(@"%i/%i",[self numerator], [self denominator]);
}