从java转向Objective(6)

在Objective-C中,小写字母和大写字母是不同的,即区分大小写。

注释:单行注释://

块注释:/*……*/

注意:注释不能嵌套使用。

换行符:\n 

输出操作:NSLog(@”内容”);

类、对象和方法

什么是对象?对象就是一个食物。把面向对象的程序设计看成一个事物,而且想对这个事物做些功过,这与C语言不同,C语言通常称作过渡性语言。在C语言中,通常是先考虑要做什么,然后才关注对象,这几乎总是与面向对象的思考过程相反。

程序在逻辑上分为3个部分:

@interface部分

用来描述类、类的数据成分以及类的方法;

@implementation部分

包括实现这些方法的实际代码

@program部分

包含实现程序预期目的的程序代码。

以上每个部分都是每个Objective-C程序的一部分,它们分别放到一个单独的文件中。

@interface部分,定义新类时,首先要通知Objective-C编译器这个类来自何处,就是说,必须命名它的父类。其次必须确定这个类对象要存储的数据的类型,必须描述类成员将包含的数据,我们把这些成员叫做实例变量。最后定义在处理该类的对象时将要用到的各种操作或方法的类型。这些工作都在程序中名为@interface的特殊部分内完成。格式类似于:

@interface NewClassName:ParentClassName

{

memberDeclarations;

}

methodDeclarations;

@end

按照约定,类名以大写字母开头,尽管没有要求这么做。但这种约定能使其他人在阅读你的程序时,仅仅通过观察名称的第一个字母就能把类名和其他变量类型区分开来。

Objective-C的命名规则

名称必须以字母或下划线开头,之后可以是任何(大写或小写)字母、下划线或者0到9之间的数字组合。保留字不能作为变量名,任何对Objective-C编译器有特殊意义的名称都不能作为变量名使用。

Objectiv-C中的大写字母和小写字母是有区别的。在命名类时,类名要以大写字母开始;实例变量、对象以及方法的名称,通常以小写字母开始。为使程序具有可读性,名称中要用大写字母来表示新单词的开始。例如:

AddressBook—可能是一个类名

currentEntry—可能是一个对象

current_entry—一些程序员还使用下划线作为单词的分隔符。

addNewEntry—可能是一个方法名。

示例:如下@interface部分代码:

//------@interface section ------

@interface Fraction:NSObject

{

int numerator;

int denominator;

}

-(void) print;

-(void) setNumerator:(int) n;

-(void) setDenominator:(int) d;

@end

解读:新类(NewClassName)的名称为Fraction,其父类为NSObject。NSObject类在文件NSObject.h中定义,导入Foundation.h文件时在程序中自动包括这个类。

实例变量

memberDeclarations部分制定了哪些类型的数据将要存储到Fraction中,以及这些数据类型的名称。这部分放入自己的一组花括号中。对于Fraction类而言,声明表示Fraction对象有两个名为numerator和denominator的整型成员。这一部分声明的成员称为实例变量。

每次创建新对象时,将同时创建一组新的实例变量,而且是唯一的一组。如果拥有两个Fractions,一个为FracA,另一个为FracB,那么每个对象都有自己的一组实例变量。Objective-C系统会自动追踪这些实例变量。

-(void) print;

print方法的声明,应该位于接口文件中,用来显示内容的方法(C语言)。开头的负号(-)通知Objective-C编译器,这个方法是一个实例方法。其他唯一的选择是正号(+),它表示类方法。类方法是对类本身执行某些操作的方法,例如创建类的新实例。

实例方法对类的特定实例执行一些操作,例如设置值、检索值和显示值等。

返回值,声明新方法时,必须通过Objective-C编译器这个方法是否返回值,如果返回值,那么返回哪种类型的值。将返回类型放入开头的负号或正号之后的圆括号中,可完成这项工作。

例如:-(int)retrieveNumerator;

返回值为int类型,通过return返回。

如果方法无返回值,可用void类型表示:-(void) print;无需在方法结尾执行一条return语句或执行一条不带任何指定值的return语句:return;

方法的参数:

-(void)setNumerator:(int)n;

-(void)setDenominator:(int)d;

这两个方法都是不返回值的实例方法。每个方法都有一个整型参数,这是通过参数名前面的(int)指明的。就setNumerator来说,其参数名是n。这个名称可以是任意的,它是用来引用参数的方法名称。因此,setNumerator的声明指定向该方法传递一个名为n的整型参数,而且该方法没有要返回的值。

每个方法名都以冒号结束,这个冒号通知Objective-C编译器该方法期望看到一个参数。然后指定参数的类型,并将其放入一对圆括号中,这与为方法自身指定返回类型的方式十分相似。最后使用象征性的名称来确定方法所指定的参数。整个声明以一个分号结束:

从java转向Objective


如果方法接受一个参数,那么在引用该方法时在方法名之后附加一个冒号。

@implementation部分

@implementation部分包含声明在@interface部分的方法的实际代码。在@interface部分声明方法并在@implementation部分定义给出实际的代码。

格式如下:

@implementation NewClassName

methodDefinitions;

@end

NewClassName表示的名称与@interface部分的类名相同。可以在父类的名称之后使用冒号,如同在@interface部分使用的冒号一样:

@implementation Fraction:NSObject

然而,它是可选的而且通常并不这样做。

@implementation部分中的methodDefinitions部分包含在@interface部分指定的每个方法的代码。与@interface部分类似,每种方法的定义首先指定方法(类或者实例)的类型、返回类型、参数及其类型。然而,我们并没有使用分号来结束该行,而是将之后的方法代码放入一对花括号中。如下:

//---@implementation section ---

@implementation Fraction

-(void) print

{

NSLog(@”%i/%i”,numerator,denominator);

}

-(void) setNumerator:(int) n

{

numerator =n;

}

@end

Program部分:

包含解决特定问题的代码,如果有必要,它可以跨越多个文件,但必须在其中一个地方有一个名为main的例程。通常情况下,这是程序开始执行的地方。

//---program section ----

int main(int argc,char *argv[]){

Fraction *myFraction;

//Create an instance of a Fraction

myFraction = [Fraction alloc];

myFraction = [Fraction init];

//set fraction to 1/3

[myFraction setNumerator:1];

[myFraction setDenominator:3];

//Display the fraction using the print method

NSLog(@”the value of myFraction is:”);

[myFraction print];

[myFraction release];

return 0;

}

在main中,使用以下程序行定义了一个名为myFraction的变量:

Fraction *myFraction;

这个行表示myFraction是一个Fraction类型的对象,就是说,myFraction用于存储来自新的Fraction类变量。myFraction前面的星号(*)是必需的,从技术上,它实际表示myFraction是对Fraction的一个引用(或者指针)。

现在你拥有一个用于存储Fraction的对象,需要创建一个分数:

myFraction =[Fraction alloc];

alloc是allocate的缩写。因为要为新分数分配内存空间存储空间:

[Fraction alloc]

向新创建的Fraction类发送一条消息。你请求Fraction类使用alloc方法,但是你从未定义这个alloc方法,于是此方法是来自继承一个父类的。

将alloc消息发送给一个类时,便获得该类的新实例。返回值存储在变量myFraction中。Alloc方法保证对象的所有实例变量都编程初始状态。然而这并不意味着该对象进行了适当的初始化进而可以使用。在分配对象之后,还必须对其初始化。

通过如下语句完成:

myFraction = [myFraction init];

init方法用于初始化类的实例变量。

你正在将init消息发送给myFraction,即要在这里初始化一个特殊的Fraction对象,因此它没有发送给类,而是发送给类的一个实例对象:myFraction;

init方法也可以返回一个值,即被初始化的对象。将返回值存储到Fraction的变量myFraction中。

如下两行代码分配了类的新实例并做了初始化,这两条消息在Objective-C中特别茶盎见,通常组合到一起:

myFraction = [[Fraction alloc]init];

内部消息表达式:

[Fraction alloc]

分配一个新的Fraction实力对象并分配和初始化:

Fraction *myFraction=[[Fraction alloc] init];

这种编码的风格非常重要。例如分配自动释放池:

NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];

此处将alloc消息发送给NSAutoreleasePool类,请求创建一个新实例,然后向新实例对象发送init消息以初始化该对象。

[myFraction setNumerator:1];把消息setNumerator发送给myFraction,提供一个值为1的参数。

类、对象、方法的总结:

类的声明:@interface 类名:父类名

常量、变量

方法:

-(返回值类型)方法名;

-(void)方法名:(参数类型)参数名;

负号代表实例方法,正号代表类方法;

方法的实现:@implementation类名

-(void)David

-(void)David:(int)n

对象的使用:main(@Program)中,

//创建类的实例对象并分配内存、初始化

Car *car1 = [[Car alloc] init];

等同于: Car *car1 = [Car new];

方法的调用:

[实例对象 方法名];

[实例对象 方法名:参数值];

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ppsfw.html