您的位置:首页 > 职场人生

——黑马程序员——OC中构造和重写构造方法

2015-11-07 08:04 507 查看
-----------android培训java培训、java学习型技术博客、期待与您交流!-----------
OC中构造和重写构造方法

一、构造方法

构造方法:用来初始化对象的方法,是对象方法,以 - 号开头
目的: 为了让对象创建出来,成员变量就会有一些固定的值
创建一个对象时做三件事情
如:Person *p = [Person new];
new 时 做三件事情
1、使用alloc 方法为为对象分配存储空间
2、使用init 方法对对象进行初始化
3、返回对象的首地址
也可以把以上new方法看作
1、调用类方法 + alloc 分配存储空间,返回未经初始化的对象
Person * p = [Person alloc];
2、调用对象方法 - init 进行初始化,返回对象本身
Person *p1 = [p1 init];
3、1和2两个过程整合在一起为
Person *p = [[Person alloc] init ];
注意事项:
1、init 方法就是构造方法,是用来初始化对象的方法,这是一个对象方法,以 — 号开头。默认初始化完毕后,所有成员变量的值都为0
2、alloc 向某个类发送alloc消息的结果
为该类分配内存,以存放该类的全部实例变量
将内存区域全部初始化为0
3、一个刚刚分配的对象并不能立即使用,需要先初始化该对象,然后才能使用它

二、重写构造方法

-(instancetype) init {
//先让父类吧父类原来该做的事情做完
self = [super init];
//判断父类是否初始化完成
if (self){
//此处写子类初始化的内容
_age = 10; //给年龄设置为默认值为10岁
}
//指代的是当前方法的调用者
return self;
}

#import <Foundation/Foundation.h>
//定义一个类
@interface Person: NSObject
{
@public
int _age;
}

@end

@implementation Person

//在子类中重写父类的 init 方法

-(id) init {

//调用父类的init 方法
self = [super init];

//判断父类是否初始化成功
if(self){
//给子类初始化为10
_age = 10;

}

return self;//self指代的是方法的调用者,返回的是[Pesron alloc]的地址
}

@end

int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//在此处输入Objective-C代码

Person *p = [ Person new ];
NSLog(@"p->_age = %d", p->_age);

Person *p1 = [ [Person alloc] init ];

NSLog(@"p1->_age = %d", p1->_age);

[pool drain];
return 0;
}



1、[ super init ]的作用:面向对象的体现,利用父类的init方法让父类给属性初始化

2、self = [ super init ]; 为防止父类初始化方法时release 掉 self指向的空间,重新alloc一块空间,这时[super init] 可能会 alloc 失败,此时不再执行if中的语句
3、return self ; 返回申请的新空间的首地址

三、重写构造方法(重写init方法)的应用

例:让学生继承人的类,要求学生对象初始化之后,年龄是10,学号是1
分析:要让实例变量一开始的时候就有固定的值,需要在子类中重写父类 init 的方法
1、在子类Student中重写init方法

#import <Foundation/Foundation.h>
//定义一个Person类
@interface Person: NSObject

@end

@implementation Person

@end

//定义Student类
@interface Student: Person
{
//设置实例变量为公开类型
@public
int _age;
int _num;
}
@end

@implementation Student
//在Student中重写父类的init 方法
-(id)init{

self = [super init];
if(self){
//给实例变量指定初始化
_age = 10;
_num = 1;

}

return self;
}

@end

int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//创建一个学生的对象
Student *stu = [Student new];

NSLog(@"stu->_age = %d  stu->_num = %d",stu->_age, stu->_num);

[pool drain];
return 0;
}


/

2、在Student的父类Person中重写,父类中必须要有实例变量

#import <Foundation/Foundation.h>
//定义一个Person类
@interface Person: NSObject
{
@public
int _age;
int _num;
}
@end

@implementation Person
//在Persont中重写父类的init 方法
-(id)init{

self = [super init];
if(self){
//给实例变量指定初始化
_age = 10;
_num = 1;

}

return self;
}

@end

//定义Student类
@interface Student: Person
{
//设置实例变量为公开类型
@public
int _age;
int _num;
}
@end

@implementation Student

@end

int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//创建一个学生的对象
Student *stu = [Student new];

NSLog(@"stu->_age = %d  stu->_num = %d",stu->_age, stu->_num);

[pool drain];
return 0;
}



四、自定义构造方法

作用:按照用户指定的值去给实例变量初始化
如:Person *p = [Person initWith:@"xxxxxxxx"andAge:18];这样的方式进行赋值
规范:
1、一定是对象方法,以— 号开头
2、返回值一般是 id 类型
3、方法名以 initWith开头
4、一般形式是:
(一) 需求:在创建Person类的时候把人的名称创建出来,已创建完成后就有名称

#import <Foundation/Foundation.h>
//创建Person类
@interface Person: NSObject
{
int _age;
NSString *_name;
}
-(void)setAge:(int) age;
-(void)setName:(NSString*) name;

@end

@implementation Person
-(int)age{
return _age;
}
-(NSString*)name{

return _name;
}

//重写init 方法
-(id)init{

self = [super self];
if(self){
_age = 10;
_name = @"张小三";

}
return self;
}

@end
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//未重写init方法前
Person *p = [Person new];
NSLog(@"_age =  %d _name = %@",p->_age,p->_name);

//创建新的对象p1
Person *p1 = [Person new];
//给对象实例变量赋值
p1->_age = 10;
p1->_name = @"张三";
NSLog(@"_age =  %d _name = %@",p1->_age,p1->_name);

//重写init之后
Person *p2 = [Person new];
NSLog(@"_age = %d  _name = %@",p2->_age,p2->_name);

[pool drain];
return 0;
}




(二)在以上代码的基础上实现可以 每次创建对象是用指定值给实例变量赋值

以上代码并不能满足我们的需求,因为每次创建新的对象后 实例变量的值都是默认的

#import <Foundation/Foundation.h>
//创建Person类
@interface Person: NSObject
{
int _age;
NSString *_name;
}
-(void)setAge:(int) age;
-(void)setName:(NSString*) name;
-(id)initWithAge:(int) andName:(NSString *)name;
@end

@implementation Person
-(int)age{
return _age;
}
-(NSString*)name{

return _name;
}

//重写init 方法
-(id)initWithAge:(int)age andName:(NSString *)name{

self = [super self];
if(self){
_age = age;
_name = name;

}
return self;
}

@end
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//未重写init方法前
Person *p = [Person new];
NSLog(@"_age =  %d _name = %@",p->_age,p->_name);

//创建新的对象p1
Person *p1 = [Person new];
//给对象实例变量赋值
p1->_age = 10;
p1->_name = @"张三";
NSLog(@"_age =  %d _name = %@",p1->_age,p1->_name);

//重写init之后
Person *p2 = [Person new];
NSLog(@"_age = %d  _name = %@",p2->_age,p2->_name);

//自定义构造方法
Person *p3 = [[Person alloc]initWithAge: 10 andName: @"赵四"];
NSLog(@"_age = %d  _name = %@",p3->_age,p3->_name);

[pool drain];
return 0;
}




(三)需求:在以上代码基础上创建一个学生的类并继承Person类,实现每次创建学生对象时能用指定的学生姓名、年龄和学号给实力变量赋值

#import <Foundation/Foundation.h>
//创建Person类
@interface Person: NSObject
{
int _age;
NSString *_name;
}
-(void)setAge:(int) age;
-(void)setName:(NSString*) name;
//在Person类中自定义构造方法的声明
-(id)initWithAge:(int) andName:(NSString *)name;
@end

@implementation Person
-(int)age{
return _age;
}
-(NSString*)name{

return _name;
}

//自定义构造方法的实现
-(id)initWithAge:(int)age andName:(NSString *)name{

self = [super self];
if(self){
_age = age;
_name = name;

}
return self;
}

@end

//创建Student类
@interface Student: Person
{
int _num;
}
//定义num的set、get方法
-(void)setNum:(int) num;
-(int)num;
//在Student类中自定义构造方法的声明
-(id)initWithAge:(int) age andName:(NSString *)name andNum:(int) num;

@end
@implementation Student
//实现num的get和set方法
-(void)setNum:(int) num{

_num = num;
}
-(void)age{

return _age;
}

//在Student类中自定义构造方法的实现
-(id)initWithAge:(int) age andName:(NSString *)name andNum:(int) num{

self = [super initWithAge:age andName: name];
if(self){

//_name = name  此处无法调用_name,因为_name 是父类私有的,不能继承也不能访问
//此处可以使用self调用在Person类中的构造方法
_num = num;

}
return self;
}

@end

int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//未重写init方法前
Person *p = [Person new];
NSLog(@"_age =  %d _name = %@",p->_age,p->_name);

//创建新的对象p1
Person *p1 = [Person new];
//给对象实例变量赋值
p1->_age = 10;
p1->_name = @"张三";
NSLog(@"_age =  %d _name = %@",p1->_age,p1->_name);

//重写init之后
Person *p2 = [Person new];
NSLog(@"_age = %d  _name = %@",p2->_age,p2->_name);

//创建一个学生类
Student *stu = [[Student alloc] initWithAge:28 andName:@"小沈阳" andNum: 1000];
NSLog(@"_age = %d  _name = %@  _num = %d ",stu->_age,stu->_name,stu->_num);

[pool drain];
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: