Objective-C總結(jié)----2.如何編寫一個類(上)

Objective-C是一門面向?qū)ο缶幊?OOP)語言累提,如何編寫一個類斋陪?

Objective-C類基本構(gòu)成

  • 由.h頭文件和.m實現(xiàn)文件組成,有如下基本概念:
    • 成員變量缔赠、成員屬性嗤堰、成員方法
    • 成員方法分類:類方法“+”度宦、對象方法“-”
    • 協(xié)議、分類后专、擴展

自定義一個Objective-C類

  • 創(chuàng)建一個命令行工程:自定義類.xcodeproj
Snip20161007_4.png
  • 創(chuàng)建一個自定義類:Person類戚哎,一般需要為自定義類添加個人前綴區(qū)分其他人的自定義類建瘫,防止重名沖突尸折。在工程設置選項Class Prefix填入前綴:KNZ实夹,為每次自定義類都添加個人前綴。
Snip20161007_6.png
  • command+N創(chuàng)建一個新的文件,選擇cocoa class准给,按Next
Snip20161007_8.png
  • 創(chuàng)建一個KNZPerson類露氮,并繼承于NSObject钟沛,按Next
Snip20161007_9.png
  • 確保文件添加到targets中恨统,選中勾
Snip20161007_11.png
  • 按Create莫绣,創(chuàng)建好一個KNZPerson類悠鞍,包含兩個文件:KNZPerson.h和KNZPerson.m
Snip20161007_12.png

為了這個類添加成員變量、成員屬性涧窒、成員方法

  • 成員變量:_name纠吴、_age慧瘤、_sex
    • 蘋果公司的成員變量命名規(guī)范一般以下劃線“_”開頭锅减,違反規(guī)范會產(chǎn)生各種各樣的問題怔匣。
  • 成員方法:類方法+speak,對象方法-talk
    • 類方法:向一個類發(fā)送消息;
    • 對象方法:先創(chuàng)建一個對象金闽,再向這個對象發(fā)送消息代芜。

在KNZPerson.h中聲明成員變量和成員方法:
<code>
//
// KNZPerson.h
// 自定義類
//
// Created by 李陽 on 2016/10/7.
// Copyright ? 2016年 kenzo. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface KNZPerson : NSObject
{
NSString *_name;
int _age;
BOOL _sex;//YES為男浓利,NO為女
}
+(void)speak;
-(void)talk;
@end
</code>

代碼解析

  • #import <Foundation/Foundation.h>:導入Foundation.h頭文件
    • “#”->預處理器指令贷掖,編譯前轉(zhuǎn)換為Objective-C代碼
    • Foundation羽资,為Objective-C程序提供通用的API基礎
  • @interface KNZPerson : NSObject
    • “@”->編譯指令屠升,@interface腹暖,這是個接口文件
    • KNZPerson : NSObject ->這個KNZPerson類繼承于NSObject類翰萨,NSObject類為所有類的根類,為類提供通用的接口阿蝶。
  • {
    NSString *_name;
    int age;
    BOOL sex;//YES為男黄绩,NO為女
    }
    • 成員變量必須寫在{ }里面,不可以向成員變量賦值爽丹。
  • 成員方法:+(void)speak;粤蝎、-(void)talk;
    • void 無返回值

在KNZPerson.m中實現(xiàn)KNZPerson.h中聲明的所有方法:
<code>
//
// KNZPerson.m
// 自定義類
//
// Created by 李陽 on 2016/10/7.
// Copyright ? 2016年 kenzo. All rights reserved.
//
#import "KNZPerson.h"
@implementation KNZPerson
+(void)speak
{
NSLog(@"你好初澎!speak!");
}
-(void)talk
{
NSLog(@"名字:%@,年齡:%d,男的:%hhd",_name,_age,_sex);
}
@end
</code>

  • 所有方法在@implementation KNZPerson...@end內(nèi)部實現(xiàn)
    • 類方法+speak無法訪問成員變量碑宴,除非成員變量當參數(shù)傳進來

已經(jīng)實現(xiàn)完基本的Person類,這個類有三個成員變量和兩個成員方法⊙嫘現(xiàn)在想使用這個類匕积。

  • 想使用KNZPerson這個類闪唆,先導入KNZPerson.h頭文件到main.m文件中
    <code>
    //
    // main.m
    // 自定義類
    //
    // Created by 李陽 on 2016/10/7.
    // Copyright ? 2016年 kenzo. All rights reserved.
    //
    #import <Foundation/Foundation.h>
    #import "KNZPerson.h"
    int main(int argc, const char * argv[]) {
    @autoreleasepool {
    }
    return 0;
    }
    </code>

  • 想調(diào)用類方法時钓葫,直接向類發(fā)送類方法消息

Snip20161007_14.png

- 運行帆调,直接打印“你好番刊!speak影锈!”

  • 想調(diào)用對象方法時,先去創(chuàng)建一個對象熔吗,然后向?qū)ο蟀l(fā)送對象方法消息磁滚。
    <code>
    //
    // main.m
    // 自定義類
    //
    // Created by 李陽 on 2016/10/7.
    // Copyright ? 2016年 kenzo. All rights reserved.
    //
    #import <Foundation/Foundation.h>
    #import "KNZPerson.h"
    int main(int argc, const char * argv[]) {
    @autoreleasepool {
    KNZPerson *person = [KNZPerson alloc]init;
    [person talk];
    }
    return 0;
    }
    </code>

  • KNZPerson *person = [KNZPerson alloc]init;

    • KNZPerson *person:創(chuàng)建一個KNZPerson類型指針變量person垂攘,用來接收返回的對象地址淤刃。
    • 一般來說[KNZPerson alloc]init才是真正的創(chuàng)建了一個對象逸贾,而person用來保存這個對象的地址铝侵,但是我們提到對象的話咪鲜,都是指這個保存對象地址的指針。
  • [person talk]:向這個對象person發(fā)送對象方法消息-talk颖侄。

  • 運行览祖,打印
    2016-10-07 23:30:28.489370 自定義類[20555:1243524] 名字:(null),年齡:0,男的:0
    Program ended with exit code: 0**

    • 由于初始化時展蒂,沒有給對象的成員變量賦值锰悼,所以都是默認值:基本類型為0悼泌,引用類型為空null馆里。

這次通過在.h頭文件中聲明成員變量的方法自定義一個類鸠踪,這樣設計有個弊端丙者,就是將成員變量都公開了,雖然成員變量作用范圍默認為protected营密,但不符合OOP封裝性械媒。


Snip20161008_20.png

成員變量作用范圍

  • @private
    • 將成員變量設置為只能在聲明它的類以及該類類型相同的其他實例對象中訪問
  • @protected
    • 將成員變量設置為只能在聲明它的類及其子類的實例方法中被訪問。成員變量默認范圍评汰。
  • @public
    • 將成員變量設置為可以被任何代碼訪問
  • @package
    • 將成員變量設置為可以被其它實例對象或函數(shù)訪問纷捞,但是在其所屬程序包的外部它被視為私有變量,這種作用范圍可以用于庫或者框架類被去。

因此,我們將成員變量在.m文件中聲明惨缆,并提供訪問成員變量的set/get方法,繼續(xù)改進.

  • 將成員變量寫在.m文件中糜值,這樣就不會暴露成員變量的信息了

<code>
//
// KNZPerson.m
// 自定義類
//
// Created by 李陽 on 2016/10/7.
// Copyright ? 2016年 kenzo. All rights reserved.
//
#import "KNZPerson.h"
@implementation KNZPerson
{
NSString *_name;
int _age;
BOOL _sex;//YES為男,NO為女
}
+(void)speak
{
NSLog(@"你好坯墨!speak!");
}
-(void)talk
{
NSLog(@"名字:%@,年齡:%d,男的:%d",_name,_age,_sex);
}
@end
</code>

  • 接下來在.m文件中重寫init初始化方法寂汇,給對象賦初始值。
Snip20161008_21.png
  • [super init]實際是[self init],但是調(diào)用父類的初始化init方法初始化

  • 如果初始化成功捣染,self不為nil骄瓣,執(zhí)行if里面的代碼進行成員變量初始化賦值

  • 最后返回self,這是重寫初始化方法標準格式耍攘,先調(diào)用父類的方法累贤,在判斷是否成功,如果失敗則不執(zhí)行if里面代碼少漆。

  • 運行

2016-10-08 08:04:44.487069 自定義類[24353:1473367] 名字:kenzo,年齡:20,男的:1
Program ended with exit code: 0

  • 對象已經(jīng)有初始值了臼膏,然后我再創(chuàng)建一個KNZPerson類的實例對象person2
Snip20161008_22.png
  • 運行

2016-10-08 08:08:29.781012 自定義類[24558:1485252] 名字:kenzo,年齡:20,男的:1
2016-10-08 08:08:29.781207 自定義類[24558:1485252] 名字:kenzo,年齡:20,男的:1
Program ended with exit code: 0

  • 創(chuàng)建的兩個實例對象person、person2都初始化為相同的內(nèi)容了示损,在實際開發(fā)中都是有指定初始化方法的渗磅,無論調(diào)用哪個初始化方法最后都得調(diào)用指定初始化方法,現(xiàn)在自定義指定初始化方法检访。

  • 在KNZPerson.h文件中聲明指定初始化方法

-(instancetype)initWithName:(NSString *)name age:(int)age sex:(BOOL)sex;

  • 在KNZPerson.m文件中實現(xiàn)指定初始化方法
    <code>
    -(instancetype)initWithName:(NSString *)name age:(int)age sex:(BOOL)sex
    {
    self = [super init];
    if (self) {
    _name = name;
    _age = age;
    _sex = sex;
    }
    return self;
    }
    </code>

  • 先調(diào)用父類的初始化方法始鱼,初始化成功的話執(zhí)行if里面的代碼,為每個成員變量賦值脆贵。

  • 重新創(chuàng)建person医清、person2對象
    <code>
    //
    // main.m
    // 自定義類
    //
    // Created by 李陽 on 2016/10/7.
    // Copyright ? 2016年 kenzo. All rights reserved.
    //
    #import <Foundation/Foundation.h>
    #import "KNZPerson.h"
    int main(int argc, const char * argv[]) {
    @autoreleasepool {
    KNZPerson *person = [[KNZPerson alloc]initWithName:@"kenzo" age:28 sex:1];
    [person talk];
    KNZPerson *person2 = [[KNZPerson alloc]initWithName:@"lucy" age:20 sex:0];
    [person2 talk];
    }
    return 0;
    }
    </code>

  • 一開始創(chuàng)建對象時,就可以給對象成員變量賦值

  • 運行

2016-10-08 08:24:38.128484 自定義類[25391:1536557] 名字:kenzo,年齡:28,男的:1
**2016-10-08 08:24:38.128671 自定義類[25391:1536557] 名字:lucy,年齡:20,男的:0
Program ended with exit code: 0

  • 現(xiàn)在我們創(chuàng)建了兩個不同的實例對象卖氨,但是隨著時間推移会烙,對象的年齡會不斷增加负懦,這個時候還要提供訪問成員變量的set/get方法。

    • set方法命名規(guī)范:成員變量_age=>setAge
    • get方法命名規(guī)范:成員變量_age=>age
  • 在KNZPerson.h文件中聲明set/get方法
    -(void)setAge:(int)age;

    • set方法沒有返回值柏腻,參數(shù)類型為成員變量類型

    -(int)age;

    • get方法返回值類型為成員變量類型
  • 在KNZPerson.m文件中實現(xiàn)set/get方法
    <code>
    -(void)setAge:(int)age
    {
    _age = age;
    }
    -(int)age
    {
    return _age;
    }
    </code>

  • 這樣纸厉,就可以修改和讀取對象的成員變量的值。
    <code>
    //
    // main.m
    // 自定義類
    //
    // Created by 李陽 on 2016/10/7.
    // Copyright ? 2016年 kenzo. All rights reserved.
    //
    #import <Foundation/Foundation.h>
    #import "KNZPerson.h"
    int main(int argc, const char * argv[]) {
    @autoreleasepool {
    KNZPerson *person = [[KNZPerson alloc]initWithName:@"kenzo" age:28 sex:1];
    [person talk];
    KNZPerson *person2 = [[KNZPerson alloc]initWithName:@"lucy" age:20 sex:0];
    [person2 talk];</br>
    [person setAge:29];
    [person2 setAge:21];
    NSLog(@"person:%d 歲,person2:%d 歲",[person age],[person2 age]);
    }
    return 0;
    }
    </code>

  • 先設置person的年齡為29五嫂,person2的年齡為21颗品,然后讀取打印

<code>
2016-10-08 08:39:23.815602 自定義類[26131:1582661] 名字:kenzo,年齡:28,男的:1
2016-10-08 08:39:23.815805 自定義類[26131:1582661] 名字:lucy,年齡:20,男的:0
2016-10-08 08:39:23.815843 自定義類[26131:1582661] person:29 歲,person2:21 歲
Program ended with exit code: 0
</code>

注解

需要為每一個成員變量提供set/get訪問方法,但這些重復性工作沒有多大意義沃缘,蘋果公司推出了自動聲明屬性@property躯枢,它會自動生成成員變量和對應的set/get訪問方法。下一篇:Objective-C總結(jié)----2.如何編寫一個類(下)槐臀,將以自動聲明屬性方式重構(gòu)這個KNZPerson類锄蹂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市峰档,隨后出現(xiàn)的幾起案子败匹,更是在濱河造成了極大的恐慌,老刑警劉巖讥巡,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掀亩,死亡現(xiàn)場離奇詭異,居然都是意外死亡欢顷,警方通過查閱死者的電腦和手機槽棍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抬驴,“玉大人炼七,你說我怎么就攤上這事〔汲郑” “怎么了豌拙?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長题暖。 經(jīng)常有香客問我按傅,道長,這世上最難降的妖魔是什么胧卤? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任唯绍,我火速辦了婚禮,結(jié)果婚禮上枝誊,老公的妹妹穿的比我還像新娘况芒。我一直安慰自己,他們只是感情好叶撒,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布绝骚。 她就那樣靜靜地躺著耐版,像睡著了一般。 火紅的嫁衣襯著肌膚如雪皮壁。 梳的紋絲不亂的頭發(fā)上椭更,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天哪审,我揣著相機與錄音蛾魄,去河邊找鬼。 笑死湿滓,一個胖子當著我的面吹牛滴须,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叽奥,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼扔水,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了朝氓?” 一聲冷哼從身側(cè)響起魔市,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赵哲,沒想到半個月后待德,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡枫夺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年将宪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橡庞。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡较坛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扒最,到底是詐尸還是另有隱情丑勤,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布吧趣,位于F島的核電站法竞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏再菊。R本人自食惡果不足惜爪喘,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纠拔。 院中可真熱鬧秉剑,春花似錦、人聲如沸稠诲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至略水,卻和暖如春价卤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背渊涝。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工慎璧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跨释。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓胸私,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鳖谈。 傳聞我的和親對象是個殘疾皇子岁疼,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Objective-C2.0發(fā)布,新特性:自動聲明缆娃、補全屬性捷绒、點語法,大大提高了開發(fā)效率贯要,現(xiàn)在我將用自動聲明屬性的...
    鋼鉄俠閱讀 315評論 0 1
  • 這里是引用文字暖侨,但是不知道對換行如何處理?我猜這個問號后面的內(nèi)容仍然是引用部分 據(jù)說這樣可以生成一級標題 這行應該...
    雷蒙張閱讀 136評論 0 0
  • 【七】【 王子歸來復仇 】 開掛的王子,日行千里显押,夜行八百扳肛,日夜兼程,飛奔回到大宛國乘碑。 王子飛身躍過城墻挖息,神一樣出...
    睡前童話大王閱讀 288評論 4 4
  • 姓名:易平香 企業(yè)名稱:東莞耀升機電有限公司 組別:AT感謝組/272期努力一組 【日精進打卡第61天】 【知~學...
    shine1yi閱讀 262評論 0 0
  • 想象的再多,希望的再美好兽肤,遠不如去實踐一次套腹。 今天我邁出了第一步,參加了寶貝親子園的年度答謝會走秀訓練资铡。這對我絕對...
    素素花閱讀 227評論 1 0