Objective-C面向对象-用于处理分数的 Objective-C 类
来源:互联网 发布:新加坡dfs免税店 mac 编辑:程序博客网 时间:2024/06/11 16:38
谈过了对象,实例和方法这些基本的面向对象概念后。接下来不妨定义个实际的类,并学习如何使用类的实例。进而领略Objective-C摄人心魄的秩序和美丽。
范例3-1,下面是一个简单的处理分数的程序:
01 // Simple program to work with fractions
02#import <Foundation/Foundation.h>
03
04int main (int argc, const char * argv[]) {
05 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
06 int numerator = 1;
07 int denominator = 3;
08 NSLog(@"The fraction is %i/%i", numerator, denominator);
09
10 [pool drain];
11 return 0;
12}
02
03
04
05
06
07
08
09
10
11
12
在这里,分数是以分子和分母的形式表示。创建自动释放池后,main中的前两行将变量numerator和denominator都声明为整型,并分别给它们赋值1和3,最终显示他们。似乎问题都解决了,不过试想如果程序现在需要处理的不是一个分数,而是多个。那么这种简单的过程性编码将遇到麻烦。每次要引用分数的时候,都必须引用相应的分子和分母,而且更进一步的处理也会更加复杂。
最终输出结果:
The fraction is 1/3
那么接下来,我们何不把一个分数定义成单个实体,用单个名称(例如myFraction)来共同引用它的分子和分母。
范例3-2,用一个名为Fraction的新类来重写3-1中的函数:
01 // Program to work with fractions - class version
02
03 #import <Foundation/Foundation.h>
04
05 //---- @interface section ----
06
07 @interface Fraction: NSObject
08 {
09 int numerator;
10 int denominator;
11 }
12
13 -(void) print;
14 -(void) setNumerator: (int) n;
15 -(void) setDenominator: (int) d;
16
17 @end
18
19
20 //---- @implementation section ----
21
22 @implementation Fraction
23
24 -(void) print
25 {
26 NSLog (@"%i/%i", numerator, denominator);
27 }
28
29 -(void) setNumerator: (int) n
30 {
31 numerator = n;
32 }
33
34 -(void)setDenominator: (int)d
35 {
36 denominator = d;
37 }
38 @end
39
40
41 //---- program section ----
42
43 int main (int argc, const char * argv[])
44 {
45 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
46 Fraction *myFraction;
47
48 // Create an instance of a Fraction
49
50 myFraction = [Fraction alloc];
51 myFraction = [myFraction init];
52
53 // Set fraction to 1/3
54
55 [myFraction setNumerator: 1];
56 [myFraction setDenominator: 3];
57
58 // Display the fraction using the print method
59
60 NSLog(@"The value of myFraction is:");
61 [myFraction print];
62 [myFraction release];
63
64 [pool drain];
65 return 0;
66 }
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
从代码中我们可以看到,整个程序在逻辑上分为3个部分:
@interface部分
@implementation部分
program部分
@interface部分用于描述类,类的数据成分以及类的方法;
@implementation部分包括实现这些方法的实际代码;
program部分包含实现程序目的的程序代码。
下面具体介绍每个部分
@interface部分
定义新类时,必须做一些事情。
首先,要通知Objective-C编译器这个类来自何处。换句话说,我们必须命名它的父类。
其次,确定这个类对象要存储的数据类型。就是说,必须描述类成员将包含的数据。这些成员被称为实例变量。
最后,定义在处理该类的对象时将要用到的各种操作或方法的类型。
以上工作都在程序中名为@interface的特殊部分内完成。
一般的@interface格式:
@interface NewClassName: ParentClassName
{
memberDeclarations;
}
methodDeclarations;
@end
按照约定,类名以大写字母开头!这样做的好处是其他人在阅读你的程序时,仅仅通过观察第一个字母就能把类名和其他变量类型区分开来。那除了类名,在Objective-C中制定名称的基本规则是什么?答案是:名称必须以字母或下划线(_)开头,之后可以是任何(大写或小写)字母,下滑线或者0到9之间的数字组合。不过存在少数的特例,就是被系统使用的保留字无法使用,比如int。
讲了这么多,回过头来看下本例中的情况。
newClassName 为 Fraction (新类)
ParentClassName 为 NSObject (父类)
memberDeclarations (数据类型) 不再复述。唯一需要注意的是每次创建新的对象时,将同时创建一组新的实例变量,而且是唯一一组。因此如果拥有两个Fraction,一个名为fracA,另一个名为fracB,那么每个都将有自己的一组实例变量。
methodDeclarations (方法类型)
由于你不能直接访问分数的内部表示(就是,直接访问它的实例变量),因此你必须通过定义各种方法才能使用它。
-(void) print;
开头的负号(-)通知编译器,该方法是一个实例方法。如果是加号(+),则表示是类方法。类方法之前有提过就是对类本身执行某些操作的方法。例如创建类的新实例。好比制造厂制造一辆新的汽车。在这里汽车是个类;而要造新汽车便是类方法。
言归正传,实例方法对类的特定实例执行一些操作。例如设置值,检索值和显示值等。声明方法print时,必须通知Objective-C编译器这个方法是否返回值。void代表无返回值,如果是int表示返回整型值,double则返回双精度值,以此类推。当返回值定义了void后。就无需在方法结尾执行一条return语句了,因为return就是为了返回特定的值而存在。
再看@interface中还声明了其他两个方法:
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
它们都是不返回值的实例方法。每个方法都有一个整型参数,就是通过参数名前面的(int)指明的。就setNumerator来说,其参数名是n。这个名称可以是任意的,它是用来引用参数的方法名称。总结下声明这两个方法的语法。每个方法名都以冒号结束,这个冒号通知编译器该方法期望看到一个参数。然后,指定参数的类型,并将其放入一对圆括号中,这与方法指定返回值的类型非常相似。最后,使用象征性的名称来确定方法所指定的参数。整个声明以一个分号结束。
- 实例方法
(void) 返回值类型为无返回值
setNumerator 方法名
: 该方法期望看到一个参数
(int) 参数的类型为整型值
n 象征性的名称来确定方法所定的参数
@implementation部分
在@interface所声明的方法,在@implementation定义。所谓定义就是给出实际的代码。
一般的@interface格式:
@implementation NewClassName
methodDefinitions;
@end
NewClassName表示的名称与@interface部分的类名相同。可以在其后使用冒号加上父类名称。
例如:@implementation Fraction: NSObject
不过要声明的是它是可选的,而且通常并不这么做。
在代码中,print方法使用NSLog显示变量numerator和denominator的值。setNumerator和setDenominator将参数储存到各自的实例变量中去。
program部分
在这个部分中,包含了解决特定问题的代码
Fraction *myFraction;
定义了一个名为myFraction的对象。其中的星号(*)是必须的,它实际表示myFraction是对Fraction的一个引用(或者指针)。
myFraction = [Fraction alloc];
alloc 是 allocate 的缩写,因为要为新分数分配内存存储空间。表达式[Fraction alloc]向Fraction类发送一条消息。请求使用来自父类NSObject的alloc方法。使用方法的结果就是获得该类的新实例。把返回值储存在myFraction中。
myFraction = [myFraction init];
alloc方法保证对象的所有实例变量都变成初始状态。然而,这并不意味着该对象进行了适当的初始化进而可以使用。在分配对象后还必须进行初始化,init方法用于初始化类的实例变量,同样源自继承来的父类NSObject。现在,我们正将init消息发送给myFraction。就是说,要在这里初始化一个特殊的Fraction对象,因此它没有发送给类,而是发送给类的一个实例。把返回值储存在myFraction中。
由于这两条代码在Objective-C中非常常见。通常程序员都使用它们的组合形式:
myFraction = [[Fraction alloc] init];
和算数运算法则一样,内部的[Fraction alloc]首先求值,再应用init方法。初始化的过程一次性完成后把结果赋值给myFraction。
做为最终的简写形式,经常把分配和初始化直接合并到声明行,如下所示:
Fraction *myFraction = [[Fraction alloc] init];
而这种风格的延伸,将会在以后的代码中更经常被看到:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
此处将alloc消息发送给NSAutoreleasePool类,请求创建一个新实例。然后向新创建的对象发送init消息,以初始化该对象。
剩下的代码就非常简单了,不再多说。
代码最终输出结果很简单,不过我们已经在用面向对象的思想来处理却是个质的飞跃!
The value of myFraction is:
1/3
最后分享下笔者在CSDN上传的源代码链接:Simple_Fraction
- Objective-C面向对象-用于处理分数的 Objective-C 类
- 用于处理分数的Objective-C类
- Objective C面向对象
- objective-c面向对象
- Objective-C 面向对象
- 基于Objective-C的面向对象编程
- Objective-C 面向对象的编程语言
- Objective-C 面向对象基础-类
- Objective-C 面向对象(类II)
- Objective-C语言:面向对象
- Objective-C:面向对象程序设计
- [objective-c] 面向对象1
- 【Objective-C】01-面向对象
- 【Objective-C】面向对象前奏
- Objective-C 面向对象基础
- Objective-C(一)面向对象
- Objective-c中的面向对象
- Objective-C 面向对象一
- UIDevice-with-UniqueIdentifier-for-iOS-5
- js常用代码搜集
- 2440的flash、linux、bootloader
- Objective-C面向对象-Objective-C 对象,实例和方法
- factorial,阶乘
- Objective-C面向对象-用于处理分数的 Objective-C 类
- JNI实现回调| JNI调用JAVA函数|参数和返回值的格式
- Android学习笔记--对话框
- COM笔记-CoCreateInstance
- 使用sysbench测试mysql5.5和postgre9.1性能
- Objective-C面向对象-如何在程序中使用多个分数
- Objective-C面向对象-实例变量的访问以及数据封装
- COM笔记-COM库函数
- Discuz!NT 中的LLServer架构设计