類的設(shè)計
面向?qū)ο蟮幕靖拍?/h3>
對象:在現(xiàn)實世界中對象是我們認(rèn)識世界的基本單元,在面向?qū)ο蟪绦蛟O(shè)計中對象是接收消息的單元;每個對象都是獨一無二的;對象都有屬性和行為;對象都屬于某個類关斜。
類:類是對一組具有共同屬性和行為的對象的抽象,它是創(chuàng)建對象的藍(lán)圖和模板铺浇。
消息:對象與對象之間存在著一定的聯(lián)系痢畜,這種聯(lián)系通過消息的傳遞來實現(xiàn)。面向?qū)ο笫澜缰械乃胁僮鞫际峭ㄟ^向?qū)ο蟀l(fā)送消息來實現(xiàn)随抠,對象接收到消息后裁着,會執(zhí)行對應(yīng)的行為。
面向?qū)ο蟮娜笾е?/h3>
封裝:把一個事物包裝起來拱她,使外界不了解它的內(nèi)部的具體情況二驰。在面向?qū)ο蟮某绦蛟O(shè)計中,封裝就是把相關(guān)的數(shù)據(jù)和代碼結(jié)合成一個有機(jī)的整體秉沼,形成數(shù)據(jù)和操作代碼的封裝體桶雀,對外只提供一個可以控制的接口,內(nèi)部大部分的實現(xiàn)細(xì)節(jié)對外隱蔽唬复,達(dá)到對數(shù)據(jù)訪問權(quán)的合理控制矗积。封裝使程序中各部分之間的相互聯(lián)系達(dá)到最小,提高了程序的安全性敞咧,簡化了程序代碼的編寫工作棘捣。
繼承:從已有的類創(chuàng)建新類的過程,提供繼承信息的稱為父類休建,得到繼承信息的稱為子類乍恐,子類和父類之間是IS-A關(guān)系评疗,繼承使得類與類之間形成一個層次結(jié)構(gòu)。與此同時茵烈,繼承也讓變化中的系統(tǒng)具有了穩(wěn)定性和延續(xù)性百匆。
多態(tài):不同結(jié)構(gòu)的對象可以以各自不同的方式響應(yīng)同一個消息,或者說同一個消息可以根據(jù)發(fā)送消息的對象的不同而采用多種不同的操作行為呜投,這是面向?qū)ο笞罹璧牟糠帧?/p>
定義和使用類
對象:在現(xiàn)實世界中對象是我們認(rèn)識世界的基本單元,在面向?qū)ο蟪绦蛟O(shè)計中對象是接收消息的單元;每個對象都是獨一無二的;對象都有屬性和行為;對象都屬于某個類关斜。
類:類是對一組具有共同屬性和行為的對象的抽象,它是創(chuàng)建對象的藍(lán)圖和模板铺浇。
消息:對象與對象之間存在著一定的聯(lián)系痢畜,這種聯(lián)系通過消息的傳遞來實現(xiàn)。面向?qū)ο笫澜缰械乃胁僮鞫际峭ㄟ^向?qū)ο蟀l(fā)送消息來實現(xiàn)随抠,對象接收到消息后裁着,會執(zhí)行對應(yīng)的行為。
封裝:把一個事物包裝起來拱她,使外界不了解它的內(nèi)部的具體情況二驰。在面向?qū)ο蟮某绦蛟O(shè)計中,封裝就是把相關(guān)的數(shù)據(jù)和代碼結(jié)合成一個有機(jī)的整體秉沼,形成數(shù)據(jù)和操作代碼的封裝體桶雀,對外只提供一個可以控制的接口,內(nèi)部大部分的實現(xiàn)細(xì)節(jié)對外隱蔽唬复,達(dá)到對數(shù)據(jù)訪問權(quán)的合理控制矗积。封裝使程序中各部分之間的相互聯(lián)系達(dá)到最小,提高了程序的安全性敞咧,簡化了程序代碼的編寫工作棘捣。
繼承:從已有的類創(chuàng)建新類的過程,提供繼承信息的稱為父類休建,得到繼承信息的稱為子類乍恐,子類和父類之間是IS-A關(guān)系评疗,繼承使得類與類之間形成一個層次結(jié)構(gòu)。與此同時茵烈,繼承也讓變化中的系統(tǒng)具有了穩(wěn)定性和延續(xù)性百匆。
多態(tài):不同結(jié)構(gòu)的對象可以以各自不同的方式響應(yīng)同一個消息,或者說同一個消息可以根據(jù)發(fā)送消息的對象的不同而采用多種不同的操作行為呜投,這是面向?qū)ο笞罹璧牟糠帧?/p>
定義和使用類
定義類的過程是一個抽象的過程加匈,需要進(jìn)行數(shù)據(jù)抽象和行為抽象,數(shù)據(jù)抽象是找到和對象相關(guān)的屬性仑荐,行為抽象是找到和對象相關(guān)的方法雕拼。要完成數(shù)據(jù)抽象和行為抽象,通呈推幔可以從對問題的描述中找名詞和動詞悲没,名詞會成為類或者類中的屬性,動詞會成為類中的方法男图。
類的聲明部分(.h文件)
#import <Foundation/Foundation.h>
@interface CDStudent : NSObject {
@private
NSString *_name;
NSUInteger _age;
}
- (instancetype) initWithName: (NSString *) name
age: (NSUInteger) age;
- (NSString *) name;
- (void) play: (NSString *) game;
- (BOOL) study: (NSString *) course
forHours: (NSUInteger) hours;
@end
類的實現(xiàn)部分(.m文件)
#import "CDStudent.h"
const static int MIN_STUDY_HOURS = 120;
@implementation CDStudent
- (instancetype) initWithName: (NSString *) name
age: (NSUInteger) age {
if (self = [super init]) {
_name = name;
_age = age;
}
return self;
}
- (NSString *) name {
return _name;
}
- (void) play: (NSString *) game {
NSLog(@"%@ is playing %@.", _name, game);
}
- (BOOL) study: (NSString *) course
forHours: (NSUInteger) hours {
NSLog(@"%@ is studying %@.", _name, course);
return hours >= MIN_STUDY_HOURS;
}
@end
初始化方法
上面類的定義中,以init打頭的方法稱為初始化方法甜橱,初始化方法在創(chuàng)建對象時調(diào)用以完成對對象的初始化(給對象的屬性賦初始值)
創(chuàng)建對象
CDStudent *stu = [[CDStudent alloc] initWithName:@"Alice" age:18];
給對象發(fā)消息
#import <Foundation/Foundation.h>
#import "CDStudent.h"
int main(int argc, char *argv[]) {
@autoreleasepool {
CDStudent *stu = [[CDStudent alloc] initWithName:@"Alice" age:18];
[stu play:@"LoL"];
BOOL hasFinished = [stu study:@"Objective-C" forHours:64];
NSLog(@"%@ %@ mastered Objective-C.", [stu name], hasFinished ? @"has" : @"hasn't");
}
return 0;
}
使用訪問修飾符
定義類時逊笆,可以給類中的屬性添加訪問修飾符,包括:
- @private:私有岂傲,對外界來說是不可見的(不可訪問)难裆。
- @protected:受保護(hù),對子類公開對其他類相當(dāng)于私有镊掖。
- @public:公開乃戈,對外界來說是可見的(可以訪問)。
實例方法和類方法
定義類時亩进,可以在方法的返回類型前添加-或+分別表示方法是實例方法或類方法症虑。所謂實例方法就是對象的方法,即發(fā)給對象的消息归薛,因此要創(chuàng)建對象才能調(diào)用谍憔;而類方法是類的方法,即發(fā)給類的消息主籍,可以直接通過類名進(jìn)行調(diào)用习贫,不需要創(chuàng)建該類的對象。我們可以再添加一個類方法來創(chuàng)建學(xué)生對象千元,具體的代碼如下所示苫昌。
+ (instancetype) studentWithName: (NSString *) name
age: (NSUInteger) age;
+ (instancetype) studentWithName: (NSString *) name
age: (NSUInteger) age {
// 類方法中的self代表CDStudent類
return [[self alloc] initWithName:name age:age];
}
// 直接給類發(fā)消息來創(chuàng)建和初始化學(xué)生對象
CDStudent *stu = [CDStudent studentWitWithName:@"Alice" age:18];
那么問題來了,哪些方法應(yīng)該設(shè)計成實例方法幸海,哪些方法應(yīng)該設(shè)計成類方法呢祟身?通常來說屋厘,一個方法與對象狀態(tài)無關(guān)只跟類有關(guān)就要設(shè)計成類方法,反之就要設(shè)計成實例方法月而。