【Objective-C】11-构造方法



一、构造方法的作用:

构造方法是用来初始化对象的方法,是个对象方法,-开头。构造方法只有一个作用,就是初始化成员变量。当一个对象初始化的时候需要有默认值,就可以用到构造方法。

二、构造方法的原则:

成员变量属于哪个类,就在哪个类那里进行初始化。父类的属性交给父类方法去处理,子类方法处理子类自己的属性。 


三、构造方法的应用场景:

        3.1 new方法的调用

new方法是一个类方法,它是alloc类方法和init对象方法的连合体,相当于new方法内部调用了alloc方法和init方法。因此当有重写init方法时,调用new方法时,它内部就会调用init方法进行初始化。一般使用类似于:Person *p=[Person new];完整地创建一个对象会有以下两个步骤:

 1>分配存储空间(new方法内部调用+alloc)

`2>初始化  (new方法内部调用-init)


3.2 重写-init方法

1>init是一个对象方法,可以通过类似于:Person *p=[[Person alloc] init];来显式地调用init方法进行初始化。

2>重写init方法,在方法内部开头一定要调用回super的init方法,来对父类中声明的一些变量和属性进行初始化。调用super的init方法成功后,才有必要进行接下来的初始化。初始化成功后返回一个已经初始化完毕的对象。

3>子类重写父类的init方法,只需要初始化自己声明的成员变量。父类的成员变量可以由父类自己进行初始化。这样可以避免当父类成员变量名有所改动时,而导致的连环改动。


3.3 自定义构造方法

1>当需要通过外部传递参数给构造方法进行指定成员变量的初始化时,就需要用到自定义构造方法。这种初始化方式比较灵活。

2>自定义构造方法的规范:一定是对象方法,一定以-开头;返回值一般是id类型;方法名一般以initWith开头。

3>当需要初始化父类的成员变量时,尽量使用父类提供的构造方法进行初始化父类的成员变量。


#import <Foundation/Foundation.h>
@interface Person :NSObject

@property int age;
@property NSString *name;

//返回值是id类型
-(id)initWithAge:(int)age;
-(id)initWithName:(NSString *)name;
-(id)initWithAge:(int)age andName : (NSString *)name;

@end

@implementation Person
//重写init方法,在方法内部开头一定要调用回super的init方法,来对父类中声明的一些变量和属性进行初始化。调用super的init方法成功后,才有必要进行接下来的初始化。初始化成功后返回一个已经初始化完毕的对象。
- (id)init
{
	//如果父类对象初始化成功,就进行接下来的成员变量的初始化
	if (self = [super init]){
		_age = 20;
	}
	//返回一个已经初始化完毕的对象
	return self;
}
/*这种方式比较繁琐,一般采用上面那种方式重写构造方法
	-(id)init
	{
	//调用super的init方法:初始化父类中声明的一些成员变量和其他属性并返回给self
	self=[super init];
	//如果对象初始化成功,才有必要进行接下来的初始化
	if(self!=nil)
	{
	//初始化成功后初始化成员变量
	_age=20;
	}
	//返回一个已经初始化完毕的对象
	return self;
	}
*/

/*
	自定义构造方法的实现
	自定义构造方法的规范:
	1.一定是对象方法,一定以-开头;
	2.返回值一般是id类型;
	3.方法名一般以initWith开头。
*/
-(id)initWithAge:(int)age
{
	if (self = [super init])
	{
		_age = age;
	}
	return self;
}
-(id)initWithName:(NSString *)name
{
	if (self = [super init])
	{
		_name = name;
	}
	return self;
}
-(id)initWithAge:(int)age andName : (NSString *)name
{
	if (self = [super init])
	{
		_age = age;
		_name = name;
	}
	return self;
}

@end

@interface Student : Person
@property int no;
-(id)initWithName:(NSString *)name andAge : (int)age andNo : (int)no;
@end

@implementation Student
//注释与Person重写init方法一样,Person重写了NSObject的init方法
- (id)init
{
	if (self = [super init])
	{
		_no = 1;
	}
	return self;
}
// 父类的属性交给父类方法去处理,子类方法处理子类自己的属性
-(id)initWithName:(NSString *)name andAge : (int)age andNo : (int)no
{
	// 将name、age传递到父类方法中进行初始化
	if (self = [super initWithAge : age andName : name])
	{
		_no = no;
	}
	return self;
}

/* 这种采用self来初始化父类成员变量的方式比较少用
	- (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no
	{
		if ( self = [super init] )
		{
			_no  = no;
			//_name = name;
			self.name = name;//点语法
			self.age = age;

			//[self setName:name];//self调用:默认先查找当前子类的方法,如果找不到再到父类方法中查找
			//[self setAge:age];
		}
		return self;
	}
*/
@end

int main()
{
	/*
	new方法是一个类方法,它是alloc类方法和init对象方法的连合体,相当于new方法内部调用了alloc方法和init方法。调用new方法时,它内部就会调用init方法进行初始化。完整地创建一个对象会有以下两个步骤:
	1>分配存储空间(new方法内部调用+alloc)
	2>初始化  (new方法内部调用-init)
	*/
	Person *p1 = [Person new];
	NSLog(@"通过new方法获得这个人%d岁了", p1.age);

	Person *p2 = [[Person alloc]init];
	NSLog(@"通过init方法获得这个人%d岁了", p2.age);

	Student *s1 = [[Student alloc]init];
	NSLog(@"子类对象Student重写init方法之后,学号是%d,年龄是%d", s1.no, s1.age);

	Person *p3 = [[Person alloc]initWithAge:11];
	NSLog(@"通过自定义构造方法initWithAge方法获得这个人%d岁了", p3.age);

	Person *p4 = [[Person alloc]initWithName:@"Jack"];
	NSLog(@"通过自定义构造方法initWithName方法获得这个人%d岁了,名字是%@", p4.age, p4.name);

	Person *p5 = [[Person alloc]initWithAge:12 andName : @"Tom"];
	NSLog(@"通过自定义构造方法initWithAgeandName方法获得这个人%d岁了,名字是%@", p5.age, p5.name);

	Student *s2 = [[Student alloc]initWithName:@"Jim" andAge:15 andNo : 2];
	NSLog(@"子类对象Student重写initWithAgeandNameandNo方法之后,学号是%d,年龄是%d,名字是%@", s2.no, s2.age, s2.name);

	return 0;
}

输出结果:

2015-02-07 09:41:51.878 a.out[534:13741] 通过new方法获得这个人20岁了
2015-02-07 09:41:51.880 a.out[534:13741] 通过init方法获得这个人20岁了
2015-02-07 09:41:51.880 a.out[534:13741] 子类对象Student重写init方法之后,学号是1,年龄是20
2015-02-07 09:41:51.880 a.out[534:13741] 通过自定义构造方法initWithAge方法获得这个人11岁了
2015-02-07 09:41:51.881 a.out[534:13741] 通过自定义构造方法initWithName方法获得这个人0岁了,名字是Jack
2015-02-07 09:41:51.881 a.out[534:13741] 通过自定义构造方法initWithAgeandName方法获得这个人12岁了,名字是Tom
2015-02-07 09:41:51.881 a.out[534:13741] 子类对象Student重写initWithAgeandNameandNo方法之后,学号是2,年龄是15,名字是Jim



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值