1.什么是复合?在Objective-C 中,复合是通过包含作为实例变量的对象指针实现的:(我们定义一辆车有一个发动机和四个轮,程序如下)[plain] view plaincopy #import@interface Tire : NSObject
@end//Tire接口
@implementation Tire
- (NSString *) description
{
return(@"I am a tire, I last a while");
}//description的实现
@end//Tire的实现
@interface Engine : NSObject
@end//Engine接口
@implementation Engine
- (NSString *) description
{
return(@"I am an engine. Vroom!");
}
@end//Engine的实现
@interface Car : NSObject
{
Engine *engine;
Tire *tires[ 4 ];
}
- (void) print;
@end//Car接口
@Implementation Car
- (id) init
{
if (self = [super init] ){
engine = [ Engine new ];
tires[ 0 ] = [ Tire new ];
tires[ 1 ] = [ Tire new ];
tires[ 2 ] = [ Tire new ];
tires[ 3 ] = [ Tire new ];
}
return(self);
}//init方法实现
-(void) print
{
NSLog (@"%@" , engine);
NSLog (@"%@" , tires[0]);
NSLog (@"%@" , tires[1]);
NSLog (@"%@" , tires[2]);
NSLog (@"%@" , tires[3]);
}//print方法的实现
@end//Car的实现
int main (int argc, const char * argv[ ])
{
Car *car;
car = [ Car new];
[ car print ];
return (0);
}//main :运行结果为,I am an engine, Vrooml
I am a tire , I last a while.
I am a tire , I last a while.
I am a tire , I last a while.
I am a tire , I last a while.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2.下面我来详解看看这个程序要注意的一些地方:
(1)自定义NSLog( ):从上面程序我们可以看到轮和发动机都有一个description方法,程序运行时是这样的:NSlog( )给当前对象发送描述消息(description),r
然后对象的description方法生产一个NSString并返回,之后NSLog( )在其输出中包含这个字符串。在类中添加description方法就可以自定义NSLog( )如何输出对象
(2)engine和tires实例变量是复合的,因为它们是Car的实例变量。每个Car对象都会为指向engine和tires的指针分配内存,但是真正包含在Car中的并不是engine
和tires变量,而只是内存中存在的其他对象的引用。这些指针开始会被初始化为nil(零值)
(3)来看看Car类做了些什么,第一步,为对象分配内存,即对象获得一个用来存放其实例变量的内存块,第二步,自动调用init方法,让对象处于可以状态。
(4) if (self = [super init] )这句的具体含义在后面会说明。
3.存取方法:
(1)什么是存取方法?它是来读取或改变对象特定属性的方法。一般分为,setter方法和getter方法。看看一下例子:
[plain] view plaincopy
@interface Car : NSObject
{
Engine *engine;
Tire *tires[ 4 ];
}
-(Engine *) engine;
-(void *) setEngine : (Engine *)newEngine;
-(Tire *) tireAtindex : ( int ) index;
-(void) setTire: (Tire *)tire
atIndex: (int) index;
-(void) print;
@ens//Car
@implementation Car
-(Engine *) engine
{
return (engine);
}//engine
-(void )setEngine : (Engine *) newEngine
{
engine = newEngine;
}//setEngine
-(void) setTire : (Tire *) tire
atindex : (int) index
{
if(index < 0 || index > 3){
NSLog (@"bad index (%d) in setTire : atIndex : ", index);
exit (1);
}
tires[ index ] = tire;
}//seTire : atIndex :
-(Tire *) tireAtIndex : (int) index
{
if( index < 0 || index >3){
NSLog (@"bad index (%d) in "tireAtIndex :" , index );
exit (1);
}
return (tires [ index ] );
}//tireAtIndex :
@end//Car的实现
//////////////////////////////////////////////////////////////////////////////////////////////////////////
想实际使用这些存取方法,可以像下面这样写:Engine *engine = [ Engine new ] ;
[ car setEngine : engine ];
NSLog (@"the car Engine is %@" , [car engine]);
Tire *tire = [ Tire new ];
[car setTire : tire
atIndex : 2 ];
NSLog (@"tire number two is %@",[ car tireAtIndex : 2 ]);
4.以上程序需要注意的一些地方:
(1)setter方法根据它所更改的属性的名称来命名,并加上前缀”set“,而getter方法则仅仅根据其返回的属性名称来命名前面不加”get“
(2)在以上程序中可以看到:-(void) setTire : (Tire *) tire atindex : (int) index ,设置轮的方法,这方法这样写是什么意思呢?由于汽车的4个轮胎都有自己不同的位置,所以为汽车配置某个轮胎的时候,不仅要知道使用哪个轮胎,还要清楚每个轮在 汽车上的位置,同样,当访问汽车上某个轮胎时,也要指定这个轮的具体位置才行
5.添加了设置属性和获取属性等存储方法后对应的main()函数:
[plain] view plaincopy
int main (int argc, const char * argv[ ])
{
Car *car = [Car new];
Engine *engine = [Engine new];
[ car setEngine : engine ];
int i;
for (i = 0 ; i <4 ; i++){
Tire *tire = [ Tire new];
[car setTire : tire
atIndex : i ];
}
[ car print ];
return(0);
}//main,输出结果与之前一样
6.另外我们还可以自定义两个类,分别继承Engine和Tire,并且可以对它的方法复写。具体怎么复合和继承配合使用这里就不多说了,比较简单~
7.判断是复合还是继承的方法很简单:当某件事物里有什么这是复合,当某事物是什么这是继承,用这个方法就能简单的把它们区分开来。
OC是增强了C的特性,所以在变量和基本数据类型上基本与C一致。在OC中变量命名有如下规则:由字母、数字、下划线、$符号组成必须以字母、下划线、$符号开头大小写敏感在OC中定义变量的时候不能使用OC的保留字,OC的保留字如下:OC中有如下基本数据类型:int:声明整型变量double:声明双精度变量float:声明浮点型变量char:声明字符型变量id:通用的指针类型enum:声明枚举类型long:声明长整型变量或函数short:声明短整型变量或函数signed:声明有符号类型变量struct:声明结构体变量union:声明共用体(联合)数据类型unsigned:声明无符号类型变量void:声明函数无返回值或无参数据类型格式化字符:数据类型 oc关键字 格式说明引导符整型 int %d.%i短整型 short int %hd.%hi长类型 long int %ld.%li无符号短整型 unsigned int %u无短整型 unsigned short %hu无符号长整型 unsigned long %lu浮点型 float %f双精度型 double %f长双精度型 long double %lf字符型 char %c下面有一个例子程序:[plain] view plain copy// // main.m // mxy01-dataType // // Created by mxy on 13-9-7. // Copyright (c) 2013年 mxy. All rights reserved. // #importint main(int argc, const char * argv[])
{
@autoreleasepool {
//保留字是不能定义为变量名的,例如下面的int、float等就不能作为变量名
int i = 2;
float f = 2.3f;
double d = 2.3e12;
char c = 'a';
//输出数据
NSLog(@"i : %d",i);
NSLog(@"f : %f 截取后 : %.2f",f,f);
NSLog(@"d : %e 截取后 : %.2e",d,d);
NSLog(@"c : %c , %d",c ,c );
//数据转换
//数据类型容量大的转成小的可能会丢失精度
int i2 = (int)f;
float f2 = (float)i ;
NSLog(@"数据转换");
NSLog(@"i2 : %d",i2);
NSLog(@"f2 : %f",f2);
NSLog(@"变量的作用域");
if(YES){
int i3 = 2;
NSLog(@"i3 : %d",i3);
}
//在if的{}外面是无法访问到内部的i3变量的,因为i3变量的作用域就只是那对{}内部
//NSLog(@"i3 : %d",i3);
/*
网友评论