温故而知新之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 方法,更容易理解些;
举个汽车的例子:
在没有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 方法,更容易理解些;
相关文章推荐
- 通过PropertyDescriptor反射获取属性的 getter/setter 方法
- OC学习 第二章便利初始化 便利构造器 getter/setter方法
- OC中内存管理 assign, retain, copy 的 setter 和 getter 方法
- Javascript魔法方法:__defineGetter__,__defineSetter__
- object c @synthesize 自动生成setter,getter方法
- property属性的setter、getter方法
- 使用lombok包自动生成pojo 类的getter,setter方法
- IOS-getter和setter方法
- Java网络编程从入门到精通(17):Socket类的getter和setter方法(1)
- 玩转Eclipse — 自动生成setter和getter方法
- 关于setter 和 getter方法的一些总结(初级)
- 图解教程]Eclipse不可不知的用法之一:自动生成Getter、Setter和构造方法
- WhiteStarUML增加getter、setter方法
- Java网络编程从入门到精通(18):Socket类的getter和setter方法(2)
- 浅谈 JS 对象添加 getter与 setter 的5种方法以及如何让对象属性不可配置或枚举
- lombok注解为java类生成Getter/Setter方法
- getter-setter方法 和 自定义代码块
- property生成属性的时候,同时重写setter与getter方法,那么实例变量不自动生成
- js根据属性动态生成getter、setter方法
- 如果将synthesize省略,语义特性声明为assign retain copy时,自己实现setter和getter方法