在之前谈了大量的关于 Objective-C 的基础内容,如程序循环,构造选择和使用表达式后。今天 Mike 终于可以和大家重新出发,继续以 类 作为切入点谈起,开始真正的 Objective-C 编程之旅。这篇文章的主旨首先是建立个真正意义上的 Project (范例 7-1),将类的声明和定义放在单独的文件中,不再象原来那样全部堆在一起。
第一步,打开 Xcode,新建个称为 FractionTest 的项目。对新建项目不清楚的朋友可以参考《如何搭建和使用 Xcode 开发环境》一文,在 FractionTest.m 中键入以下程序:
01 #import "Fraction.h"
02
03 int main (int argc, const char * argv[])
04 {
05 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
06 Fraction *myFraction = [[Fraction alloc] init];
07
08 // Set fraction to 1/3
09
10 [myFraction setNumerator: 1];
11 [myFraction setDenominator: 3];
12
13 // Display the fraction
14
15 NSLog(@"The value of myFraction is:");
16 [myFraction print];
17
18 [myFraction release];
19
20 [pool drain];
21 return 0;
22 }
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
大家会注意到,该文件未包括 Fraction 类的定义。然而,它却导入了一个称为 Fraction.h 的文件。
第二步,通常类的声明 (@interface 部分) 要放在它自己的名为 class.h 的文件中。而类的定义 (@implementation 部分) 通常放在相同名称的文件中,但扩展名要使用 .m。所以把 Fraction 类的声明放到 Fraction.h 文件中,把 Fraction 类的定义放到 Fraction.m 文件中。我们回到 Xcode 环境中,在 File 菜单中选择 New File。在左侧窗格中,选择 Cocoa。在右上窗格中,选择 Objective-C 类。
第三步,点击 Next,键入 Fraction.m 作为文件名。选中 Also Create Fraction.h 框。该文件所在的位置应该与 FractionTest.m 文件的文件夹相同。
第四步,现在我们点击 Finish。Xcode 在项目中添加了两个文件:Fraction.h 和 Fraction.m。
第五步,在 Fraction.h 文件中默认的是导入 Cocoa。这里我们用不上它,所以把
#import <Cocoa/Cocoa.h>
改为
#import <Foundation/Foundation.h>
第六步,输入 Fraction 类的接口部分,代码如下:
01 //
02 // Fraction.h
03 // 0701FractionTest
04 //
05 // Created by Mike on 11-5-9.
06 // Copyright 2011 MacDev. All rights reserved.
07 //
08
09 #import <Foundation/Foundation.h>
10
11 // The Fraction class
12
13 @interface Fraction: NSObject
14 {
15 int numerator;
16 int denominator;
17 }
18
19 -(void) print;
20 -(void) setNumerator: (int) n;
21 -(void) setDenominator: (int) d;
22 -(int) numerator;
23 -(int) denominator;
24 -(double) convertToNum;
25
26 @end
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
接口文件告诉编译器 Fraction 类的外观特征,大家应该都明白,不展开了。
第七步,Fraction 类的实现细节,我们把它写入 Fraction.m 中。
01 //
02 // Fraction.m
03 // 0701FractionTest
04 //
05 // Created by Mike on 11-5-9.
06 // Copyright 2011 MacDev. All rights reserved.
07 //
08
09 #import "Fraction.h"
10
11 @implementation Fraction
12
13 -(void) print
14 {
15 NSLog (@"%i/%i", numerator, denominator);
16 }
17
18 -(void) setNumerator: (int) n
19 {
20 numerator = n;
21 }
22
23 -(void) setDenominator: (int)d
24 {
25 denominator = d;
26 }
27
28 -(int) numerator
29 {
30 return numerator;
31 }
32
33 -(int) denominator
34 {
35 return denominator;
36 }
37
38 -(double) convertToNum
39 {
40 if (denominator != 0)
41 return (double) numerator / denominator;
42 else
43 return 1.0;
44 }
45
46 @end
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
注意,我们使用了以下语句将接口文件导入到实现文件中:
#import "Fraction.h"
这样做的目的是,使编译器知道为 Fraction 类声明的类和方法。同时还能确保这两个文件的一致性。Mike 需要提醒大家的是,一般不能 (虽然可以这么做) 在实现部分重复声明类的实例变量,所以编译器需要从 Fraction.h 中包含的接口部分获得信息。
需要注意的另一件事:导入的文件要用一对双引号括起来,而不是 <Foundation/Foundation.h> 中的 < 和 > 字符。双引号用于本地文件 (你自己创建的文件),本地文件与系统文件相对,并且它们告诉编译器在哪里找到指定的文件。使用双引号,编译器一般会首先在当前目录寻找指定文件,然后再转到其他位置查找。如果有必要,可以指定编译器要查找的实际位置。
最后,大家已经可以看到测试程序 FractionTest.m 包括接口文件 Fraction.h,而不包括实现文件 Fraction.m。现在,该程序分成了三个独立的文件。对于小程序例子而言,这似乎非常浪费时间。但是,以后我们就会发现它的实用性非常明显。现在可以编译并运行程序,方法与以前使用的一样,不再细说。
FractionTest 程序在优快云的下载地址。