OC學習篇之---類的初始化方法和點文法的使用,oc初始化
昨天介紹了OC中類的定義和使用:http://blog.csdn.net/jiangwei0910410003/article/details/41657603,今天我們來繼續學習類的初始化方法和點文法的使用
一、首先來看一下類的初始化方法
在Java中我們知道一個每個類都有構造方法,這裡的初始化方法就是和構造方法一個概念的,但是這裡有一個區別是:Java中有預設構造方法,當我們去自訂構造方法的時候,這個預設構造方法就會被替換了,但是OC中是不會的,這點需要注意。
下面來看一下如何自訂初始化方法:
Person.h
//// Person.h// 03_InitDemo//// Created by jiangwei on 14-10-10.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject{ NSString *_name; NSInteger _age;}//自訂初始化方法,必須以init開頭- (id)initWithName:(NSString *)name withAge:(NSInteger)age;//列印資訊- (void)showInfo;@end這裡我們定義了一個初始化方法,對名稱和年齡進行初始化賦值操作
註:OC中自訂初始化方法的名稱必須是以init開頭
在來看一下實現:
Person.m
//// Person.m// 03_InitDemo//// Created by jiangwei on 14-10-10.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import "Person.h"@implementation Person- (id)initWithName:(NSString *)name withAge:(NSInteger)age{ //固定寫法,可以背下來哦~~ //調用父類的初始化方法 self = [super init]; if(self != nil){ _name = name; _age = age; } return self;}- (void)test{ NSLog(@"test");}- (void)showInfo{ [self test];//調用自己的方法 NSLog(@"name is %@ and age is %d",_name,_age);}@end這裡我們看到了,初始化方法返回的類型是id類型,關於OC中的
id類型,可以認為和C語言中的void*是相等的,這種類型在OC中經常被用到,還有就是
self關鍵字的使用,這裡的self關鍵字就相當於Java中的this關鍵字,指代當前類對象,還有super關鍵字,這個和Java中的
super也是一樣的,指代父類對象。還有一個是
nil,他就相當於Java中的
null,Null 物件的概念,用於判斷的。
同時這裡還要記住一點:
以後OC中自訂初始化的方法的模板:
//固定寫法,可以背下來哦~~//調用父類的初始化方法self = [super init];if(self != nil){ _name = name; _age = age;} return self;這個沒什麼好說的,就是一個模板,所以初學者就背下來吧,不過用多了,自然就記住了。
下面來看一下如何使用初始化方法:
main.m
//// main.m// 03_InitDemo//// Created by jiangwei on 14-10-10.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { //初始化方法只能調用一次 Person *person = [[Person alloc] initWithName:@"jiangwei" withAge:22]; [person showInfo]; person = [[Person alloc] init]; [person showInfo]; //id類型,類似於void* //但是id類型一般不這麼使用,一般會作為方法的傳回值和傳入的參數類型 id person1 = [[Person alloc] initWithName:@"huangdaoyang" withAge:23]; [person1 showInfo]; } return 0;}我們使用了我們自訂的方法執行個體化了一個Person對象出來,同時調用他的showInfo方法,列印結果,這裡我們也會發現Person的init方法任然可以使用,這個和Java中是有區別的,其實,在上篇文章中說到過,這個init方法是NSObject父類的,可以猜想到這個方法的邏輯功能就是初始化,所以我們在自訂初始化方法的時候,都是會用到這個方法的。當然我們可以定義多個初始化方法,後面我們在介紹Foundation架構的時候,會發現系統給我提供的類有很多自訂的初始化方法。
運行結果:
二、看一下OC中的點文法
OC中的點文法其實沒什麼高端的,但是他和Java中的那種使用物件變數直接存取public類型的變數的點是不一樣的,所以這裡就單獨說明一下:
點文法只能適用於set/get方法,如果沒有對應的set/get方法的話,是不能使用.文法的
OC中的get方法和Java中不太一樣,OC中只要一個方法有傳回值都可以認為是get方法,Java中是形如getXXX這樣的才叫做get方法。
下面來看一個例子吧:
Person.h
//// Person.h// 04_UseDit//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>@interface Person : NSObject{ //點文法只能適用於set/get方法,如果沒有對應的set/get方法的話,是不能使用.文法的 //這裡的get方法和其他語言不一樣,只要有傳回值就是get方法 NSString *_name; NSInteger _age;}- (void)setName:(NSString *)name;- (void)setAge:(NSInteger)age;- (NSString *)name;- (NSInteger) age;//這裡要注意,showInfo也是一個get方法- (NSString *)showInfo;//只定義,不實現,所以在調用[person test]的時候,編譯時間候不會報錯//但是啟動並執行時候就會報錯了,因為編譯的時候只會判斷方法有沒有定義,而啟動並執行時候是需要判斷這個方法有沒有實現- (void)test;@end在{}中定義了兩個屬性,注意都是以底線開頭的。然後在給這兩個屬性定義get/set方法,這樣我們就可以使用點文法來訪問這兩個屬性了。
同時這裡要注意的是其實showInfo方法也是一個get方法,因為他又一個傳回值類型。
所以在OC中使用點文法有兩個條件:
1、必須是屬性
2、有對應的get/set方法
下面來看一下實現吧:
Person.m
//// Person.m// 04_UseDit//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import "Person.h"/** #import和#include的區別 1.當我們在代碼中使用兩次#include的時候會報錯:因為#include相當於拷貝標頭檔中的聲明內容,所以會報重複定義的錯誤 但是使用兩次#import的話,不會報錯,所以他可以解決重複匯入的問題,他會做一次判斷,如果已經匯入一次就不匯入了 */@implementation Person- (void)setName:(NSString *)name{ _name = name; NSLog(@"setName is Execute");}- (void)setAge:(NSInteger)age{ //這裡要注意,如果我們定義的全域變數是age而不是_age的話 //這裡不能用age = age進行賦值 //但是也不能使用self.age = age,因為self.age等價於[self setAge:age]這樣就會出現死迴圈了 //所以我們在定義全域變數的時候一般都會加上一個底線以便區分 _age = age; NSLog(@"setAge is Execute");}- (NSString *)name{ NSLog(@"getName is Execute"); return _name;}- (NSInteger) age{ NSLog(@"getAge is Execute"); return _age;}- (NSString *)showInfo{ NSLog(@"showInfo is Execute"); return _name;}@end我們看到了這裡對get/set方法的實現,看到上面的注釋:
我們這裡不能使用self.age = age,因為self.age等價於[self setAge:age],這樣就會出現死迴圈了
這個和Java就有很大的區別了,Java中我們是可以使用this.age = age的,而且經常這樣做,但是OC中不行,原因很簡單,因為OC中的點文法相當於調用set/get方法,那麼在set/get方法中調用set/get方法,那就會出現了死迴圈了。所以這點一定要注意。
還有一個需要注意的是,剛剛在Person.h中定義了一個test方法,但是在Person.m中並沒有實現,在OC中編譯是不會報錯的,但是啟動並執行時候就會報錯了。
看一下如何使用點文法:
main.m
//// main.m// 04_UseDit//// Created by jiangwei on 14-10-11.// Copyright (c) 2014年 jiangwei. All rights reserved.//#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *person = [[Person alloc] init]; //此處的點文法調用的是set方法,等價於[person setName:@"jiangwei"]; person.name = @"jiangwei"; person.age = 22; //此處的點文法調用的get方法,等價於NSString *name = [person name]; NSString *name = person.name; NSLog(@"name is %@",name); name = person.showInfo; NSLog(@"name is %@",name); //調用test方法 [person test]; } return 0;}我們這裡就可以使用點文法進行賦值和取值操作了,其實等價於調用他們的get/set方法。
運行結果:
這裡需要注意的是報了一個錯誤,這個錯誤也是我們後面開發過程中經常犯的一個錯誤,就是這個方法沒有實現,我們在Person.h中定義了test方法,但是沒有在Person.m中進行實現,在main.m中進行調用就報了這個錯誤,但是編譯的時候是沒有報錯的。
總結
今天就簡單的介紹了OC中的初始化方法的定義和點文法的使用,其中初始化方法類似於Java中的構造方法,點文法就是get/set的縮減版