Objective-C 2.0 学习笔记五(类)

来源:互联网 发布:ubuntu添加samba用户 编辑:程序博客网 时间:2024/05/17 01:51

变更履历

版本:v1.0

介绍

OK,这一部分是类的学习,以及如何编写方法,是的,我们之前学过如何创建方法,在这里,我们将为方法添加更多的参数,下面我们就开始吧。

分离接口和实现文件

我们知道,一个类包含两部分定义,@interface 和 @implementation,这两部分其实可以分成独立的文件存储,我们将创建两个独立的文件 Fraction.h 和 Fraction.m。@interface 位于 Fraction.h 文件中;@implementation 位于 Fraction.m 文件中。

接口文件 Fraction.h

//// Fraction.h// FractionTest//// Created by Steve Kochan on 9/29/10.// Copyright (c) ClassroomM, Inc. All rights reserved.//#import <Foundation/Foundation.h>// The Fraction class@interface Fraction : NSObject{int numerator;int denominator;}-(void) print;-(void) setNumerator: (int) n;-(void) setDenominator: (int) d;-(int) numerator;-(int) denominator;-(double) convertToNum;@end

接口文件告诉编译器 Fraction 类的外观特征。

实现文件 Fraction.m

//// Fraction.m// FractionTest//// Created by Steve Kochan on 9/29/10.// Copyright (c) ClassroomM, Inc. All rights reserved.//#import "Fraction.h"@implementation Fraction-(void) print{    NSLog (@"%i/%i", numerator, denominator);}-(void) setNumerator: (int) n{    numerator = n;}-(void) setDenominator: (int) d{    denominator = d;}-(int) numerator{    return numerator;}-(int) denominator{    return denominator;}-(double) convertToNum{    if (denominator != 0)        return (double) numerator / denominator;    else        return NAN;}@end

实现文件用来实现 Fraction 类的实现细节。import "Fraction.h" 用来将接口文件导入到实现文件中。我们注意到 import 这里使用的是双引号,而不是import <Foundation/Foundation.h> 的尖括号。双引号用于本地文件(我们自己创建的文件)。

测试程序 FractionTest.m

#import "Fraction.h"int main (int argc, char *argv[]){    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    Fraction *myFraction = [[Fraction alloc] init];    // set fraction to 1/3    [myFraction setNumerator: 1];    [myFraction setDenominator: 3];    // display the fraction    NSLog (@"The value of myFraction is:");    [myFraction print];    [myFraction release];    [pool drain];    return 0;}
我们注意到 FractionTest.m 中并没有导入实现文件。

合成存取器

在编写 Java 代码时,一个类的属性一般都会有对应的 getter/setter 方法,一般称为存取方法。OC 2.0 提供了一种简便的方式可自动生成存取方法,它是由@property @synthesize 两个关键字配合完成的。

@interface Fraction : NSObject{int numerator;int denominator;}@property int numerator, denominator;-(void) print;-(double) convertToNum;@end
这里我们并没有为 numerator 和 denominator 属性编写存取方法。
#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 NAN;}@end
下面这行内容告诉 OC 编译器,为两个实例变量(numerator 和 denominator)生成对应的存取方法:

@synthesize numerator, denominator;
通常,存储方法以 set 开头,获取方法以 get 开头,例如 getNumerator、setNumerator。

使用点运算符访问属性

点运算符(.)在 Java 中很常见,可以用来f访问除私有限定之外的属性和方法,但在 OC 中,目前为止,点运算符只能用来访问属性,这个实在没啥值得说的,[ program ] 这个方式有些邪恶啊。

多个参数的方法

好了,我们的方法终于可以有多个参数了,说实话,OC 中这种定义方法参数的方式挺让人不适用的,调用时,弄得代码老长,你说这可读性是提高了呢?还是降低了呢?好了,言归正传。

一个同时设置 numerator 和 denominator 的方法可以命名为 setNumerator:andDenominator,形式如下:

[fraction setNumerator: 1 andDenominator: 3];[fraction setTo: 1 over: 3];

上面两行代码的区别只在于命名方式,很难说哪个更好,我自己一般用第一种。我们来看看这是如何定义的:

#import <Foundation/Foundation.h>// Define the Fraction class@interface Fraction : NSObject{int numerator;int denominator;}@property int numerator, denominator;-(void) print;-(void) setTo: (int) n over: (int) d;-(double) convertToNum;@end

然后是实现文件

#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 NAN;}-(void) setTo: (int) n over: (int) d{    numerator = n;    denominator = d;}@end

测试程序

#import "Fraction.h"int main (int argc, char *argv[]){    Fraction *aFraction = [[Fraction alloc] init];    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    [aFraction setTo: 100 over: 200];    [aFraction print];    [aFraction setTo: 1 over: 3];    [aFraction print];    [aFraction release];    [pool drain];    return 0;}

不带参数名得方法

上面的缺点是,当一个方法参数很多时,可读性较差,所以 就有了另外一种编写方式:

-(int) set: (int) n: (int) m

调用时是这样写的:

[fraction set 1 : 3];

说实话,这种省略真不咋地,很难知道这个调用在做些什么。

局部变量

方法的参数和方法中定义的变量都是局部变量。对于方法参数来说,通过方法传递的任何参数都被复制到局部变量中。因为方法使用参数的副本,所以不能改变通过方法传递的原值。当然,如果参数是对象,那么是可以更改其中实例变量值的。

static 关键字

用 static 声明的变量只在程序开始执行时初始化一次。

static int hitCount = 0;
值得注意的是,OC 中的静态变量是可以用在非静态方法中的,这与 Java 是不同的。

self 关键字

self 与 java 的 this 关键字含义是一样的,但 this 在有些情况下是省略的,而 self 却不行,如方法调用:

- (void) add: (Fraction *) f{    // To add two fractions:    // a/b + c/d = ((a*d) + (b*c)) / (b * d)    numerator = numerator * f.denominator + denominator * f.numerator;    denominator = denominator * f.denominator;    [self reduce];}

在方法中分配和返回对象

直接上代码:

-(Fraction *) add: (Fraction *) f{    // To add two fractions:    // a/b + c/d = ((a*d) + (b*c)) / (b * d)    // result will store the result of the addition    Fraction *result = [[Fraction alloc] init];    result.numerator = numerator * f.denominator + denominator * f.numerator;    result.denominator = denominator * f.denominator;    [result reduce];    return result;}

上面的代码存在内存泄露的问题。这里涉及 cocoa 内存管理机制,具体请参考《iOS 内存管理编程指南》中的描述。





原创粉丝点击