ObjectiveC程序设计文档格式.docx
- 文档编号:22431040
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:28
- 大小:591.53KB
ObjectiveC程序设计文档格式.docx
《ObjectiveC程序设计文档格式.docx》由会员分享,可在线阅读,更多相关《ObjectiveC程序设计文档格式.docx(28页珍藏版)》请在冰豆网上搜索。
}
return0;
}
Objective-C源文件使用.m作为文件的扩展名。
表1.1列出了常见的文件扩展名。
表1.1
代码解释:
(1)注释:
//或/**/
(2)将文件信息导入或者包含到文件中,其中包含其他类和函数的有关信息。
(3)main特殊名称,准确地表示程序在何处执行。
(4)“autoreleasepool”自动释放池:
使得应用在创建对象时,系统能够有效地管理应用所使用的内存。
(5)调用名为NSLog的函数,传递给NSLog函数的参数是字符串:
“@HelloWorld!
”(@符号位于一对双引号的字符串前面,成为NSString对象)。
NSLog不仅能显示简单短语,还能显示变量的值及计算结果。
例如,
NSLog(@"
Thesumof%iand%iis%i"
value1,value2,sum);
可以按格式输出变量的值。
二、Objective-C程序设计初步
2.1基本数据类型和表达式
2.1.1基本数据类型
与C++语言基本相同,不同的是,Objective-C添加了一种id类型,id数据类型可存储任何类型的对象,从某种意义上说,它是一般对象类型。
id类型是多态和动态绑定的基础。
基本数据类型如表2.1所示,
表2.1
2.1.2表达式
与所有的程序设计语言一样,运算符具有优先级,优先级较高的运算符首先求值。
如果优先级相同,可按照“从左到右”或者“从右到左”的方向来求值,具体按哪个方向取值取决于运算符。
例如常见的算术运算符、逻辑运算符、赋值运算符等等。
2.2基本控制结构
与大多数程序设计语言相似,包括顺序、选择、循环结构,在此不再累述。
三、类、对象与方法入门
3.1基本概念
⑴对象
对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
⑵对象的状态和行为
对象具有状态,一个对象用数据值来描述它的状态。
对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。
对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中
⑶类
具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。
因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。
类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。
类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。
⑷类的结构
在客观世界中有若干类,这些类之间有一定的结构关系。
通常有两种主要的结构关系,即一般--具体结构关系,整体--部分结构关系。
①一般--具体结构称为分类结构,也可以说是“或”关系,或者是“isa”关系。
②整体--部分结构称为组装结构,它们之间的关系是一种“与”关系,或者是“hasa”关系。
⑸消息和方法
对象之间进行通信的结构叫做消息。
在对象的操作中,当一个消息发送给某个对象时,消息包含接收对象去执行某种操作的信息。
发送一条消息至少要包括说明接受消息的对象名、发送给该对象的消息名(即对象名、方法名)。
一般还要对参数加以说明,参数可以是认识该消息的对象所知道的变量名,或者是所有对象都知道的全局变量名。
类中操作的实现过程叫做方法,一个方法有方法名、返回值、参数、方法体。
3.2Objective-C中的面向对象
下面采用面向对象的方法编写一个用于处理分数的程序,代码如下所示,
//---@interface部分---
@interfaceFraction:
NSObject
-(void)print
-(void)setNumberator:
(int)n;
-(void)setDenominator:
(int)d;
@end
//---@implementation部分---
@implementFraction
intnumerator;
intdenominator;
%i/%i"
numerator,denominator);
(int)n
numerator=n;
(int)d
denominator=d;
//---program部分---
intmain(intargc,char*argv[])
Fraction*myFraction;
//创建一个分数实例
myFraction=[Fractionalloc];
myFraction=[myFractioninit];
//设置分数为1/3
[myFractionsetNumerator:
1];
[myFractionsetDenominator:
3];
//使用打印方法显示分数
ThevalueofmyFractionis:
[myFractionprint];
@interface部分用于描述类和类的方法;
@implementation部分用于描述数据(类对象的实例变量存储的数据),并实现在接口中声明方法的实际代码;
program部分实现了程序的预期目的。
(1)@interface部分
包含两个部分,首先需要告诉Objective-C编译器该类来自何处,也就是说,必须为它的父类命名。
其次,必须定义在处理该类的对象时将要用到的各种操作或方法的类型。
该部分的一般格式类似于下列语句:
@interfaceNewClassName:
ParentClassName
propertyAndMethodDeclarations;
Objective-C中变量的名称必须以字母或下划线(_)开头,之后可以是任何字母、下划线或者0~9之间的数字组合。
对于大小写敏感。
确定名称时,应该能反映变量或对象使用意图的名称。
Objective-C中的方法分为类方法和实例方法,其中,负号(-)表示是实例方法,正号(+)表示是类方法。
方法的完整定义如图2.1所示,
图2.1方法定义
(2)@implementation部分
@implementation部分包含声明在@interface部分的方法的实际代码,且需要指定存储在类对象中的数据类型。
在@interface部分声明方法,并在@implementation部分定义它们。
@implementation部分的一般格式如下:
@implementationNewClassName
memberDeclarations;
methodDefinitions;
其中,memberDeclarations部分指定了哪种类型的数据将要存储到Fraction中,以及这些数据类型的名称。
在这一部分声明的变量成为实例变量。
methodDefinitions部分包含在@interface部分指定的每个方法的代码中。
每种方法的定义通过方法的类型、返回值和参数进行标识。
2.3program部分
program部分包含解决特定问题的代码,必须有一个名为main()的函数作为程序开始的地方。
如前段代码所述,
通过以下程序行定义了一个名为myFraction的变量:
Fraction*myFraction;
这一行表示myFraction是一个Fraction类型的对象(*号表明myFraction是Fraction对象的引用,存储了一个内存地址,表明对象数据在内存中的位置)。
使用myFraction=[[Fractionalloc]init]向某个类发送alloc消息获得该类的新实例,alloc保证所有的实例变量都变成初始状态。
使用init方法初始化类的实例变量,init方法返回一个值,即被初始化的对象。
下一步,程序行[myFractionsetNumerator:
1]将控制转到Fraction类中定义的setNumerator方法,将myFraction的分子设置为1。
四、Objective-C中的类
4.1分离接口和实现文件
通常,将类的声明(即@interface部分)放在它自己的名为class.h文件中。
而类的定义(即@implementation部分)通常放在相同名称的文件中,但扩展名为.m。
将接口和实现的部分分别放入两个文件,编译器会单独编译每个文件。
要使用该类,只需导入接口文件即可。
当编译器处理包含实现部分的文件时,需要接口部分的信息,因此需要导入.h文件。
要把包含main函数的文件名保存为main.m,作为程序的入口。
4.2合成存取方法
从Objective-C2.0开始,可自动生成设值方法和取值方法(统称为存取方法)。
首先,在接口部分使用@property指令标识属性。
这些属性的命名与实例变量相同。
然后,在实现部分使用@synthesize指令。
例如,接口部分有如下代码,
@interfaceFraction:
NSObject
@propertyintnumerator,denominator;
-(void)print;
-(double)convertToNum;
#import"
Fraction.h"
在实现部分,没有包含下列设值和取值方法的定义:
numerator、denominator、setNumber:
和setDenominator。
使用@synthesize指令让编译器自动生成或合成这些方法。
@implementationFraction
@synthesizenumerator,denominator;
-(double)convertToNum
if(denominator!
=0)
return(double)numerator/denominator;
else
returnNAN;
4.3使用点运算符访问属性
Objective-C语言允许使用点运算符获取所需值。
例如,myFraction.numerator等价于[myFractionnumerator],还可以使用点运算符进行赋值,例如myFraction.numerator=1等价于[myFractionsetNumerator:
1]。
4.4具有多个参数的方法
通过列出每个连续的参数并用冒号将其连接起来,就可以定义一个接收多个参数的方法。
用冒号连接的参数将成为这个方法名的一部分。
例如,在接口文件中添加setTo:
over:
声明,
#import<
//定义Fraction类
@interfaceFraction:
-(void)setTo:
(int)nover:
然后,在实现中添加新方法的定义。
@synthesizenumerator,denominator;
(int)d
7.5局部变量、方法参数、静态变量
局部变量、方法参数、静态变量与C语言类似,不再累述。
需要强调的是,局部变量使用前必须初始化,静态变量会自动初始化。
7.6self关键字
关键字self用来指明对象是当前方法的接收者。
例如,有如下代码,
-(void)add:
(Fraction*)f
numerator=numerator*f.denominator+denominator*f.numerator;
denominator=denominator*f.denominator;
[selfreduce]
在add:
消息中编写[selfreduce],就可以对Fraction应用reduce方法,它正是add:
消息的接收者,执行add:
方法时,self是作为Fraction的引用,分数会得到约减。
五、继承
5.1根类
没有父类的类位于类层次结构的最顶层,称为根(root)类。
自定义的类都属于NSObejct根类的派生类。
5.2通过继承来扩展
与C++、java等面向对象语言相似,Objective-C中定义的父类的非私有实例变量和方法都会称为新类定义的一部分。
@interfaceClassA:
intx;
-(void)initVar;
@implementationClassA
-(void)initVar
x=100;
定义一个名为ClassB的新类,继承自ClassA
@interfaceClassB:
ClassA
-(void)printVar;
@implementationClassB
-(void)printVar
x=%i"
x);
5.3方法覆写
与其他面向对象语言类似,在子类中使用和父类相同的名称定义的方法代替或覆写父类中的方法,新方法必须具有相同的返回类型,并且参数的数目要与覆写的方法相同。
如果在不同的类中有名称相同的方法,则根据作为消息的接收者的类选择正确的方法。
六、多态、动态类型、动态绑定
6.1多态
多态按字面的意思就是“多种状态”。
在面向对象语言中,接口的多种不同的实现方式即为多态。
多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
简单的说,就是一句话:
允许将子类类型的指针赋值给父类类型的指针。
C++中,实现多态有以下方法:
虚函数,抽象类,覆盖,模板。
6.2动态绑定和id类型
id可以用来存储属于任何类的对象,会导致程序无法区分某个实例对象到底是哪个类的对象。
Objective-C总是先判定对象所属的类,然后在运行时确定需要动态调用的方法,而不是在编译时。
换句话说,动态绑定指的就是在程序运行时才能确定对象的属性和需要响应的消息。
Complex.h"
intmain(intargc,char*argv[])
iddataValue;
Fraction*f1=[[Fractionalloc]init];
Complex*c1=[[Complexalloc]init];
[f1setTo:
2over5];
[c1setReal:
10.0andImaginary:
2.5];
//dataValue获得了一个分数
dataValue=f1;
[dataValueprint];
//dataValue获得了一个Complex数
dataValue=c1;
return0;
当系统将print消息发送给dataValue时,它首先会检查dataValue中存储的对象所属的类。
结合多态、动态绑定,可以轻易地编写出可以向不同类的对象发送相同消息的代码。
例如,考虑可用来在屏幕上绘制对象的draw方法。
你可能为每个图像对象(比如文本、圆、矩形、窗口,等等)定义了不同的draw方法。
如果要绘制的特定对象存储在一个名为currentObject的id变量中,仅仅通过发送draw消息就可以在屏幕上进行绘制,语句如下,[currentObjectdraw]。
6.3编译时和运行时检查
因为存储在id变量中的对象类型在编译时无法确定,所以一些测试会推迟到运行时进行。
Fraction*f1=[[Fractionalloc]init];
[f1setReal:
当编译此段代码时,将显示以下消息:
'
Fraction'
maynotrespondto'
setReal:
andImaginary:
'
现在考虑下面的代码序列:
iddataValue=[[Fractionalloc]init];
[dataValuesetReal:
10.0andImaginary:
2.5];
这段代码在编译时,编译器并不知道存储在dataValue中的对象类型,直到运行时,会出现如下出错信息:
-[FractionsetReal:
]:
unrecognizedselectorsenttoinstance0x103f00
将一个变量定义为特定类的对象时,应尽量使用静态类型。
“静态”指的是对存储在变量中对象的类型进行显式声明。
这时候,编译器能够通过检查确定应用于对象的方法是由该类定义的还是由该类继承的,否则将显示警告信息。
编译时进行的类型检查的要点如下,
(1)对于id类型的变量,调用任何方法都能够通过编译。
(2)Id类型的变量和被定义为特定类的变量之间可以相互赋值。
(3)被定义为特定类对象的变量(静态类型)如果调用了类或方法中未定义的方法,编译器就会提示警告。
(4)若是静态类型的变量,子类类型的实例变量可以赋值给父类类型的实例变量。
(5)若要判断到底是哪个类的方法执行了,不要看变量所声明的类型,而要看实际执行时这个变量的类型。
(6)Id类型并不是(NSObject*)类型。
6.4使用@try处理异常
在Objective-C中,处理异常情况的语法格式为,
@try{
statement
...
@catch(NSException*exception){
七、分类和协议
7.1分类与扩展
有时候在面对一个类定义时,可能想要添加一些新方法。
例如,对于Fraction类,除了将两个分数相加的add:
方法之外,还想要将两个分数相减、相乘、相除的方法。
分类提供了一种简单的方式,用它可以将类的定义模块化到相关方法的组或分类中。
它还提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无须创建子类。
-(Fraction*)add:
(Fraction*)f;
-(void)reduce;
从接口部分删除add:
方法,并将其添加到新分类,同时添加其他三种要实现的数学运算。
新的MathOps分类的接口部分代码如下:
@interfaceFraction(MathOps)
(Fraction*)f;
-(Fraction*)mul:
-(Fraction*)sub:
-(Fraction*)div:
其中,Fraction(MathOps)表示正在为Fraction类定义新的分类,并且它的名称为MathOps。
注意,分类不能添加新的实例变量。
创建一个未命名的分类,且在括号“()”之间不指定名字,这种特殊的语法格式定义称为类的扩展。
与分类不同的是,扩展可以添加新的实例变量。
注意,未命名分类中的方法都是私有的,如果需要写一个类,而且数据和方法仅供这个类本省使用,未命名分
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ObjectiveC 程序设计