【Objective-C】11-構造方法

hong321發表於2015-02-07



一、構造方法的作用:

構造方法是用來初始化物件的方法,是個物件方法,-開頭。構造方法只有一個作用,就是初始化成員變數。當一個物件初始化的時候需要有預設值,就可以用到構造方法。

二、構造方法的原則:

成員變數屬於哪個類,就在哪個類那裡進行初始化。父類的屬性交給父類方法去處理,子類方法處理子類自己的屬性。 


三、構造方法的應用場景:

        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



相關文章