【Objective-C】05-第一個OC的類

來源:互聯網
上載者:User

標籤:

本文目錄
  • 一、文法簡介
  • 二、用Xcode建立第一個OC的類
  • 三、第一個類的代碼解析
  • 四、新增成員變數
  • 五、添加方法
  • 六、跟Java的比較
  • 七、建立對象
  • 八、訪問公用成員變數和方法

說明:這個Objective-C專題,是學習iOS開發的前奏,也為了讓有物件導向語言開發經驗的程式員,能夠快速上手Objective-C。如果你還沒有編程經驗,或者對Objective-C、iOS開發不感興趣,請忽略。學習本專題之前,建議先學習C語言專題。

OC是一門物件導向的語言,因此它也有類、對象、靜態\動態方法、成員變數的概念。這講就來建立第一個OC的類。

回到頂部一、文法簡介1.類

在Java中,我們用1個.java檔案就可以描述清楚一個類;在OC中,一般用2個檔案來描述一個類:

1> .h:類的聲明檔案,用於聲明成員變數、方法。類的聲明使用關鍵字@interface和@end。

注意:.h中的方法只是做一個聲明,並不對方法進行實現。也就是說,只是說明一下方法名、方法的傳回值類型、方法接收的參數類型而已,並不會編寫方法內部的代碼。

2> .m:類的實現檔案,用於實現.h中聲明的方法。類的實現使用關鍵字@implementation和@end。

 

2.方法

1> 方法的聲明和實現,都必須以 + 或者 - 開頭

  • + 表示類方法(靜態方法)
  • - 表示對象方法(動態方法)

2> 在.h中聲明的所有方法範圍都是public類型,不能更改

 

3.成員變數

成員變數的常用範圍有3種:

1> @public 全域都可以訪問
2> @protected 只能在類內部和子類中訪問
3> @private 只能在類內部訪問

比Java少了一種範圍:包許可權範圍,原因很明顯:OC沒有包名的概念。

 

回到頂部二、用Xcode建立第一個OC的類

 1.右擊專案檔夾或者檔案,選擇"New File"

 

2.選擇Cocoa的"Objective-C class"

 

3.輸入類名和選擇父類

這裡的類名為Student,父類是NSobject

 

4.建立完畢後,項目中多了兩個檔案

* Student.h是類的聲明檔案,Student.m是類的實現檔案

* 預設情況下,這2個檔案的檔案名稱跟類名一致

* 編譯器只會編譯.m檔案,並不會編譯.h檔案

 

回到頂部三、第一個類的代碼解析1.Student.h - 類的聲明檔案
1 #import <Foundation/Foundation.h>2 3 @interface Student : NSObject4 5 @end

1> 看第3行,OC中使用關鍵字@interface來聲明一個類,@interface後面緊跟著類名Student。

2> 類名Student後面的冒號":"表示繼承,即第3行代碼的意思是Student繼承自NSObject。

3> 因為NSObject被聲明在Foundation.h中,所以在第1行用#import包含了Foundation.h檔案。

4> 第5行的@end表示類的聲明結束了。@interface和@end是配套使用的。

 

2.Student.m - 類的實現檔案
1 #import "Student.h"2 3 @implementation Student4 5 @end

1> 看第3行,OC中使用關鍵字@implementation來實現一個類。@implementation後面緊跟的類名,表示究竟要實現哪一個類。

2> 因為Student這個類是聲明在Student.h中的,所以在第1行用#import包含了Student.h檔案。如果你不包含Student.h,第3行代碼肯定報錯,因為它根本不知道Student是個什麼鬼東西。

3> 第5行的@end表示類的實現結束了。@implementation和@end是配套使用的。

 

回到頂部四、新增成員變數

正常情況下,我們都是把成員變數定義在標頭檔中,也就是類的聲明檔案(.h)中

1.給Student添加一個成員變數
1 #import <Foundation/Foundation.h>2 3 @interface Student : NSObject {4     int age; // 年齡5 }6 7 @end

1> 第4行定義了一個int類型的成員變數age,age的預設範圍是@protected,即可以在Student類內部和子類中訪問

2> 成員變數必須寫在大括弧{ }裡面

 

2.設定成員變數的範圍

接下來給Student增加幾個不同範圍的成員變數

 1 #import <Foundation/Foundation.h> 2  3 @interface Student : NSObject { 4     int age; // 年齡 5      6     @public 7     int no; // 學號 8     int score; // 成績 9     10     @protected11     float height; // 身高12     13     @private14     float weight; // 體重15 }16 17 @end

一共有5個成員變數,其中

@public範圍的有:no、score

@protected範圍的有:age、height

@private範圍的有:weight

 

回到頂部五、添加方法

前面我們定義了一個成員變數age,它的範圍是@protected,外界不能直接存取它。為了保證物件導向資料的封裝性,我們可以提供age的get方法和set方法,讓外界間接訪問age。接下來在Student中添加age的get方法和set方法。

1.在Student.h中聲明方法
 1 #import <Foundation/Foundation.h> 2  3 @interface Student : NSObject { 4     int age; // 年齡 5      6     @public 7     int no; // 學號 8     int score; // 成績 9     10     @protected11     float height; // 身高12     13     @private14     float weight; // 體重15 }16 17 // age的get方法18 - (int)age;19 20 // age的set方法21 - (void)setAge:(int)newAge;22 23 @end

1> 第18行聲明了age的get方法,方法名就叫做age,OC建議get方法的名字跟成員變數保持一致(如果是在Java中,就應該叫做getAge)

2> 第18行最面的 - 表示這是一個動態方法( + 則表示靜態方法)。age前面的(int)表示方法的傳回值為int類型,方法的傳回值和參數類型都需要用小括弧()包住

3> 第21行聲明了age的set方法,前面的 - 表示動態方法,(void)表示方法沒有傳回值

4> 在OC方法中,一個冒號:對應一個參數。由於第21行age的set方法接收一個int類型的參數,參數名為newAge,所以(int)newAge前面有一個冒號:

5> 一定要記住:一個冒號:對應一個參數,而且冒號:也是方法名的一部分。因此第21行set方法的方法名是setAge:,而不是setAge

 

再加大一下難度,假如增加一個方法可以同時設定age和height,那麼就應該這樣寫:

1 - (void)setAge:(int)newAge andHeight:(float)newHeight;

* 這個方法是動態方法、沒有傳回值,接收2個參數,所以有2個冒號:

* 這個方法的方法名是setAge:andHeight:

* 其實andHeight是可以省略的,它只是為了讓方法名念起來通順一點,也讓(float)newHeight前面的冒號:不那麼孤單

 

2.在Student.m中實現方法

前面已經在Student.h中聲明了3個方法,接下來一一實現它們

 1 #import "Student.h" 2  3 @implementation Student 4  5 // age的get方法 6 - (int)age { 7     // 直接返回成員變數age 8     return age; 9 }10 11 // age的set方法12 - (void)setAge:(int)newAge {13     // 將參數newAge賦值給成員變數age14     age = newAge;15 }16 17 // 同時設定age和height18 - (void)setAge:(int)newAge andHeight:(float)newHeight {19     age = newAge;20     height = newHeight;21 }22 @end

第6行對age方法進行了實現,第12行對setAge:方法進行了實現,第18行對setAge:andHeight:方法進行了實現

 

回到頂部六、跟Java的比較

如果是在Java中,一個Student.java檔案就可以搞定成員變數和方法

 1 public class Student { 2     protected int age; 3     protected float height; 4      5     public int no; 6     public int score; 7      8     private float weight; 9 10     /**11      * age的get方法12      */13     public int getAge() {14         return age;15     }16     17     /**18      * age的set方法19      */20     public void setAge(int newAge) {21         age = newAge;22     }23     24     /**25      * 同時設定age和height26      */27     public void setAgeAndHeight(int newAge, float newHeight) {28         age = newAge;29         height = newHeight;30     }31 }

 

回到頂部七、建立對象

前面已經定義了一個Student類,成員變數和方法都有了,接下來看一下怎麼使用這個類建立對象。

由於OC程式的進入點是main函數,所以在main.m檔案中示範Student類的使用。

先上完整代碼

 1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3  4 int main(int argc, const char * argv[]) 5 { 6     @autoreleasepool { 7         Student *stu = [[Student alloc] init]; 8          9         [stu release];10     }11     return 0;12 }
1.包含Student.h

因為要用到Student這個類,所以在第2行包含了它的標頭檔

#import "Student.h"

 

2.建立對象1> 在Java中是使用關鍵字new來建立對象,比如new Student(),其實這句代碼做了2件事:
  • 給對象分配儲存空間
  • 調用Student的構造方法進行初始化
2> 在OC中建立對象也需要按順序做上面所述的2件事

1)調用Student類的靜態方法alloc分配儲存空間

Student *stu = [Student alloc];
  • OC是方法調用是用中括弧[ ],方法調用者寫在括弧左側,方法名寫在括弧右側,中間留點空格。因此上面是調用了Student類的靜態方法alloc。
  • 上面調用的alloc方法會返回分配好記憶體的Student對象,在等號左邊用了一個指向Student類型的指標變數stu來接收這個對象,注意stu左邊的*號。所有OC對象都是用指標變數來接收的,如果你不瞭解指標,你記住下面這點就行了:利用類名定義一個變數時,類名後面一定要帶個*號。
  • alloc方法是這樣聲明的:
+ (id)alloc;

可以看到,它的傳回值類型是id,這個id代表任何指標類型,你可以暫時理解為:id可以代表任何OC對象,類似於NSObject *。

 

2)調用Student對象的構造方法init進行初始化

前面調用alloc方法返回的Student對象stu是不能正常使用的,因為僅僅是分配了記憶體,並沒有進行初始化,接下來調用對象的init方法進行初始化

stu = [stu init];

看清楚了,由於init是動態方法,所以這裡使用stu變數來調用,並不是使用類名來調用。init會返回已經初始化完畢的對象,再次賦值給了stu變數。這時候的Student對象stu才能正常使用。

 

3)其實,我們最常見的做法是將alloc和init連起來使用:

Student *stu = [[Student alloc] init];

相信有物件導向開發經驗的你一眼就能看懂了,在main.m完整代碼的第7行。

 

3.銷毀對象

由於OC不支援記憶體回收,因此當不再使用某個對象時,需要調用對象的release方法釋放此對象。我們在第9行銷毀了stu對象。

[stu release];

這個release方法在這裡調用一次即可,不要覺得多調用多幾次,對象就會釋放地乾淨一點,這樣做會很危險,容易造成野指標錯誤。

 

4.其他

1> 也可以調用靜態方法new快速建立一個對象

1 Student *stu = [Student new];2 3 [stu release];

不過我們還是習慣使用alloc和init來建立對象

2> 前面我們調用了Student的alloc、init、new方法,但是你會發現Student.h中並沒有聲明這些方法,為什麼能夠調用呢?原因很簡單,這些方法都是父類NSObject的,子類當然可以調用父類的方法。

 

回到頂部八、訪問公用成員變數和方法

前面已經成功建立了一個Student對象,接下來訪問一下它的公開變數和方法。

 1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3  4 int main(int argc, const char * argv[]) 5 { 6     @autoreleasepool { 7         Student *stu = [[Student alloc] init]; 8          9         // 訪問公開變數no10         stu->no = 10;11         12         // 調用setAge:方法設定變數age的值13         [stu setAge:27];14         15         // 調用setAge:andHeight:方法同時設定變數age和height的值16         [stu setAge:28 andHeight:1.88f];17         18         // 訪問公開變數no19         int no = stu->no;20         // 調用age方法擷取變數age的值21         int age = [stu age];22         23         // 列印no和age的值24         NSLog(@"no is %i and age is %i", no, age);25         26         [stu release];27     }28     return 0;29 }

1.第7行建立了Student對象,第26行銷毀了對象

2.第10行和第19行訪問了Student對象的公用成員變數no,如果不是公開變數,不能像這樣直接存取。注意訪問方式:對象->成員變數

3.第13行調用了Student對象的setAge:方法,傳入參數27修改了成員變數age的值

4.第16行調用了Student對象的setAge:andHeight:方法,同時修改了成員變數age和height的值

5.第21行調用了Student對象的age方法擷取成員變數age的值

6.第24行輸出了age和no的值,輸出結果:

2013-04-06 21:54:56.221 第一個OC程式[1276:303] no is 10 and age is 28

【Objective-C】05-第一個OC的類

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.