【黑马程序员】-我的OC学习笔记(3)-存取器方法和构造方法重写

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

OC中有一类方法称之为存取器方法,也就是我们常说的存取器set和get方法,其主要是用来进行类中实例变量的访问和赋值。

  一、OC中传统的get和set方法

@interface Person : NSObject
{
	int _age;
	NSString *_name;
}
-(void)setAge:(int)age;
-(void)setName:(NSString *)name;
-(int)age;
-(NSString *)name;
@end

     如上述代码所示,创建一个Person类,其有两个实例变量age和name。我们手动为其编写get和set方法,通过手动的get和set方法,我们能够访问age和name也可以为age和name赋值。传统的get和set方法的书写规则如下:

1、get方法以减号开头,返回类型为实例变量的类型,方法名为实例变量去除下划线的名字;

2、set方法以减号开头,返回类型为void,方法名为set后加实例变量名去除下划线并大写首字母;

3、get方法一定有返回值,set方法其后一定要有参数,且参数类型与实例变量类型想同,形参名为实例变量名去除下划线。

二、@property和@synthesize关键字

在OC中提供了一种快速实现存取器方法的编译指令,就是@property和@synthesize方法,通过这两条编译器指令我们可以不用像传统的写法那样写多个get、set方法。会由系统默认生成get和set方法。如下代码所示:

//Person.h
#import <Foundation/Foundation.h>

@interface Person
{
	int _age;
	NSString *_name;
}
@property int age;
@property NSString *name;
@end

//Person.m
#import "Person.h"
 
@implementation Person
@synthesize age;
@synthesize name;
@end;
  我们重写了上述的Peron类,并使用了@property和@synthesize指令,这时系统会在编译时为我们自动生成之前我们手动书写的传统get和set方法。@property指令的书写规则为:@property 实例变量类型 去掉set的方法名,如上例所示@property int age;指令相当于声明如下两个方法:-(void) setAge:(int) age和-(int)age方法,注意只是声明并没有实现。而且@property指令必须书写在@interface 和@end之间,并且当有多个实例变量的类型一致时可以将同类型的写在一个@property指令之后。我们在实现文件中可以使用@synthesize指令来生成对应的get和set方法的具体实现,@synthesize指令的语法是:@synthesize 去掉set的方法名。如上例所示:@synthesize age指令将会对-(void) setAge:(int) age和-(int)age方法进行具体的实现,但千万注意的是这里的这两个方法的具体实现是如下所示的代码:

-(void)age
{
	return age;
}

-(int)setAge:(int)age
{
	self->age = age;
}
其具体实现并不是我们所料想的对_age和_name进行设值和取值,而是@synthesize方法会生成两个新的实例变量age和name。并且新实例变量age和name是私有的,并且不能被子类继承和访问,如果我们想用这种语法进行对_age和_name的存取,则我们可以使用@synthesize为指定实例变量赋值的语法,例如:@synthesize age = _age,

@synthesize name = _name,这样存取器方法就会对_age和_name进行处理。

三、增强的@property

XCode4.4版本之后对@property指令进行了增强,在增强版本的@property指令中我们不需要在类的实现文件中使用@synthesize指令就可以生成类的get和set方法。例如我们再重写上述的Person类。

//Person.h
#import <Foundation/Foundation.h>

@interface Person
{
	int _age;
	NSString *_name;
}
@property int age;
@property NSString *name;
@end

//Person.m
#import "Person.h"

@implementation Person
@end;
此时我们不需要使用@synthesize方法也会生成完整的get和set方法,并且我们可以省略对于实例变量_age和_name的声明书写,因为@property会自动为我们生成对于_age和_name的声明。对于当前指令,我们可以在实现文件中重写get和set方法但是注意的是我们不能同时重写这两个方法,而只能重写两者中的一个。

四、构造器方法重写

OC中我们在初始化一个变量对象时会使用类似与如下的一条语句,比如我们定义一个Person *p = [Person new];其实这句话相当于如下两句话:Person *p = [Person alloc];[p init];这两句话分别为p对象分配了内存空间和进行了初始化,init方法我们一般就称为构造器方法。默认的构造器方法继承自NSObject类,但默认的构造器方法所能提供的功能有限,因此我们可以选择自己重写构造器方法。重写构造器方法的语法如下:

-(id)init
{
	if (self = [super init])
	{
		/.....初始化代码....*/
	}

	return self;
}
构造方法重写的语法就如上述所示,构造器方法是一个对象方法,所以以减号开头,其后跟init方法名,在方法体内首先执行if (self = [super init])命令,super指令将会执行当前类的父类的方法。这句话是为了检测父类的初始化是否成功并且分配了内存,否则我们可能会丢失父类的初始化信息。随后我们才编写自己的初始化策略,当初始化赋值完成后,我们需要返回当前对象self,self是OC中的一个特殊的标识符,其代表当前对象。例如我们可以重写Person类的构造器方法,让对象在new之后初始姓名为小明,年龄为:0。

//Person.m
#import "Person.h"

@implementation Person
-(id)init
{
	if (self = [super init])
	{
		_age = 0;
		_name = @"小明";
	}

	return self;
}
@end;
除了对系统默认的构造方法的重写,我们也可以自定义构造方法,自定义构造方法一般满足如下几点要求:

(1)一定是对象方法,以减号开头;

(2)返回值一般是id类型;

(3)方法名一般以initWith开头;

比如我们自定义Person类的构造方法,使其在执行初始化时就可以指定参数name和age,代码如下:

//Person.h
#import <Foundation/Foundation.h>

@interface Person
{
	int _age;
	NSString *_name;
}
@property int age;
@property NSString *name;
-(id)initWithName: (NSString *name) name andAge: (int) age;
@end

//Person.m
#import "Person.h"

@implementation Person
-(id)initWithName: (NSString *name) name andAge: (int) age
{
	if (self = [super init])
	{
		_name = name;
		_age = age;
	}

	return self;
}
@end;
所以当我们在创建一个Person类时可以按如下形式进行书写,Person *p = [[Person alloc] initWithName:@"小红" andAge: 18];,这样我们就完成了在创建时指定参数进行初始化。










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值