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

来源:互联网 发布:淘宝上传流通许可证 编辑:程序博客网 时间:2024/05/23 01:17

------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