这次我们要来写一支程式,稍微复杂一点,比较接近真正的程式专案,包括以下特色:
(1) 专案由三个模组所构成,通常程式为了方便管理,不会把所有的程式码,写在一起:
- MyReal 类别,一个简单的实数(real number) 类别
- MyComplex 类别,一个简单的复数 (complex number) 类别
- SimpleApp 则是主程式
(2) 使用 @property 跟 @synthesize 让 Objective-C 的编译器,帮我们产生 get/set 的程式
(3) 我们要来测试 Objective-C 的 动态型别(dynamic typing),及动态系结(dynamic binding)
以下是具体的步骤:
(1) 用 Xcode 新增一个专案,叫 SimpleApp,选项如下图
(2) 接着用 Xcode 新增一个新类别,叫 MyReal
(3) MyReal 这个类别很单纯,就是用来放一个实数(real number),特别注意,我们用 @property 来让 Objective-C 编译器帮我们产生 get/set 的程式码。另外有两个操作(method),一个 add,用来加总两个 MyReal,还有一个 print,用来列印 MyReal 的内容。名字是故意取的,等一下看到 MyComplex 类别,你就明白了。
1: //2: // MyReal.h3: // SimpleApp4: //5: // Created by Chou Shunyuan on 5/14/10.6: // Copyright 2010 __MyCompanyName__. All rights reserved.7: //8:9: #import <Foundation/Foundation.h>10:11:12: @interface MyReal : NSObject13: {14: double real;15: }16:17: @property double real;18:19: -(MyReal*) add: (MyReal*) var;20: -(void) print;21:22: @end23:
1: //2: // MyReal.m3: // SimpleApp4: //5: // Created by Chou Shunyuan on 5/14/10.6: // Copyright 2010 __MyCompanyName__. All rights reserved.7: //8:9: #import "MyReal.h"10:11:12: @implementation MyReal13:14: @synthesize real;15:16:17: -(MyReal*) add: (MyReal*) var18: {19: MyReal *result = [[MyReal alloc] init];20:21: result.real = self.real + var.real;22:23: return result;24: }25:26: -(void) print27: {28: NSLog(@"%g", real);29: }30:31: @end32:
(4) 接着依样画葫芦,产生一个 MyComplex 类别,用来放一个复数。
(5) MyComplex 里面有两个变数,一个 real,用来放复数的实数部份,一个 imaginary 用来放复数的虚数部份,特别注意,也是用 @property 跟 @synthesize 让 Objective-C 帮我们产生存取的 get/set 程式码。另外有也 add 操作,来加总两个 MyComplex,跟 print 操作,来列印 MyComplex 的内容。
1: //2: // MyComplex.h3: // SimpleApp4: //5: // Created by Chou Shunyuan on 5/14/10.
6: // Copyright 2010 __MyCompanyName__. All rights reserved.7: //8:9: #import10:11:12: @interface MyComplex : NSObject
13: {14: double real;
15: double imaginary;
16: }17:18: @property double real;19: @property double imaginary;20:21: -(MyComplex*) add: (MyComplex*) var;22: -(void) print;23:24: @end
25:
1: //2: // MyComplex.m3: // SimpleApp4: //5: // Created by Chou Shunyuan on 5/14/10.
6: // Copyright 2010 __MyCompanyName__. All rights reserved.7: //8:9: #import "MyComplex.h"
10:11:12: @implementation MyComplex13:14: @synthesize real, imaginary;15:16: -(MyComplex*) add: (MyComplex*) var17: {18: MyComplex *result = [[MyComplex alloc] init];19:20: result.real = self.real + var.real;21: result.imaginary = self.imaginary + var.imaginary;22:23: return result;
24: }25:26: -(void) print27: {28: NSLog(@" %g + %gi", real, imaginary);
29: }30:31: @end
32:
(6) 接下来是 SimpleApp 程式本体,AddTest() 这个函式,就是用来测试 Objective-C 的动态型别,跟动态系结。很神奇的,只要传给 AddTest() 的物件,有实做 add() 跟 print() 这两个操作,程式就会在执行时,正确的呼叫物件的这两个操作。特别注意,MyReal 跟 MyComplex 是两个完全不相干的类别,并非有共同的父类别(parent class)。动态系结,给 Objective-C 提供非常大的弹性,是 Objective-C 比其他语言,如 C++ 跟 Java 方便的地方。
1: #import "MyReal.h"
2: #import "MyComplex.h"
3:4: void AddTest(id var1, id var2)5: {6: id result = [var1 add: var2];7:8: [result print];9:10: [result release];11: }12:13:14: int main (int argc, const char * argv[])15: {16: NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];17:18: MyReal *realNum1 = [[MyReal alloc] init];19: MyReal *realNum2 = [[MyReal alloc] init];20:21: MyComplex *complexNum1 = [[MyComplex alloc] init];22: MyComplex *complexNum2 = [[MyComplex alloc] init];23:24: realNum1.real = 1.0;25: realNum2.real = 2.0;26:27: complexNum1.real = 3.0;28: complexNum1.imaginary = 4.0;29:30: complexNum2.real = 5.0;31: complexNum2.imaginary = 6.0;32:33: AddTest(realNum1, realNum2);34: AddTest(complexNum1, complexNum2);35:36: [realNum1 release];37: [realNum2 release];38: [complexNum1 release];39: [complexNum2 release];40:41: [pool drain];42: return 0;
43: }44:
(7) SimpleApp 首先初始化两个 MyReal 变数,一个给 1.0,另外一个给 2.0。接着初始化两个复数,一个 3 + 4i,另一个 5 + 6i,然后呼叫 AddTest 两次,第一次传两个 MyReal,第二次传两个 MyComplex。结果很神奇的居然可以正确执行。
未完待续,下次我们再来看看 Objective-C 的特异功能………