您的位置:首页 > 其它

温故而知新之setter getter 方法

2013-04-13 08:56 295 查看
setter getter 方法统称为存取方法,ObjectiveC中,在对其他对象的属性进行操作时,应该始终使用对象所提供的存取方法,永远不要直接改变其他对象属性的值。

举个汽车的例子:

在没有setter getter 方法时,我们会这样来构造一辆汽车:(最简单的汽车包括一个发动机和4个轮胎)

class Engine.h

@interface Engine :NSObject

@end

class Engine.m

@implementation Engine

-(NSString *) description{

return @"I am an engine. Vroom!";

}

@end

class Tires.h

@interface Tires :NSObject

@end

class Tires.m

@implementation Tires

-(NSString *) description{

return @"I am a tire. I last a while."'

}

@end

class Car.h

@interface Car : NSObject

{

Engine *engine;

Tires *tires[4];

}

-(void)print;

@end

class Car.m

@implementation Car

-(id) init{

if(self = [super init]){

engine = [Engine new];

tires[0] = [Tires new];

tires[1] = [Tires new];

tires[2] = [Tires new];

tires[3] = [Tires new];

}

return self;

}

-(void) print{

NSLog(@"%@",engine);

NSLog(@"%@",tires[0]);

NSLog(@"%@",tires[1]);

NSLog(@"%@",tires[2]);

NSLog(@"%@",tires[3]);

}

@end

main.m

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

{

Car *car;

car = [Car new];

[car print];

return 0;

}

在用setter 和 getter 方法后,Engine 和 Tires 类中代码不变,主要变化代码如下:

class Car.h

@interface Car : NSObject

{

Engine *engine;

Tires *tires[4];

}

-(void) setEngine:(Engine *)newEngine;

-(Engine *) engine;    //getter方法不能用get作为方法的前缀,get 在cocoa中有着特殊的含义;

-(void) setTire:(Tires *)tire atIndex:(int)index;

-(Tires *) tireAtIndex:(int) index;

-(void)print;

@end

class Car.m

@implementation

//setter 方法setEngine:将实例变量engine的值设为方法参数所指向的值,实际上被复制的并不是engine本身,而是指向engine的指针值,例如指针 *p1,*p1->engine ,调用setter 方法后,会给engine自动复制一个指针*p2,同时,让 *p2->engine,所以,实质上还是只存在一个发动机;

-(void) setEngine:(Engine *)newEngine{

engine = newEngine;

}

//getter方法,在ObjectiveC中,所有对象间的交互都是通过指针实现的,所以方法返回一个指针,指向发动机对象;

-(Engine *) engine{

return engine;

}

//用到了防御式编程思想;

-(void) setTire:(Tires *)tire atIndex:(int)index{

if(index < 0 || index > 3){

NSLog(@"bad index %d in setTire:atIndex:",index);

exit(1);

}

tires[index] = tire;

}

-(Tires *) tireAtIndex: (int)index{

if(index < 0  || index > 3){

NSLog(@"bad index %d in tireAtIndex:",index);

exit(1);

}

return tires[index];

}

-(void) print{
NSLog(@"%@",engine);
NSLog(@"%@",tires[0]);
NSLog(@"%@",tires[1]);
NSLog(@"%@",tires[2]);
NSLog(@"%@",tires[3]);
}
@end

main:

int main(int argc, const char * arcv[]){

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;

}

程序到这里就全部结束了,两次的运行结果完全相同,但是,有没有觉得后面的代码会更容易理解呢,Car中的初始化init方法没有了,取而代之的是 setter 方法,更容易理解些;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: