什么是類
具有某些相同屬性和行為,被歸為同一類。
例如:汽車是一個類,具有相同的屬性:輪子,發(fā)動機(jī),相同的行為:剎車,加速。
奔馳是汽車類的一個實(shí)例
抽象:類是一個高度抽象的概念。當(dāng)我們說某人有一臺汽車的時候,我們不知道某人擁有的是一臺什么樣的汽車。我們只能抽象出一個概念。抽象就是抽取出象的部分。
類定義了對象將會擁有的屬性和方法。類的屬性(property)和方法(method )
類和對象的關(guān)系
類是對象的類型。我們已經(jīng)學(xué)習(xí)了不少的數(shù)據(jù)類型:int ,float,double,chart。這些都是oc定義好的類型。
當(dāng)我們描述一輛奔馳的時候,他的類型就是汽車。
@interface和@implementation
類通過兩個單獨(dú)的文件定義(.h、.m)。第一個文件是接口文件,擴(kuò)展名為.h,該文件的主要作用是說明此類有哪些屬性和方法,但不去實(shí)現(xiàn)。第二個文件是實(shí)現(xiàn)文件,擴(kuò)展名為.m,具體實(shí)現(xiàn)了接口文件中聲明的方法。
在oc中,類的特征是用變量來表示的,這種變量就被稱為實(shí)例變量(或者叫做成員變量)。
@implementation 是一個編譯器指令,表示你將為某個類提供代碼。類名在@implementation之后,該行的結(jié)尾處沒有分號,因?yàn)樵贠C編譯器指令后不必使用分號。
OC中,你可以在@implementation中定義那些在@interface中無相應(yīng)的方法,可以把他們看成私有方法,僅在類的實(shí)現(xiàn)中使用。但是,你也許認(rèn)為,既然單獨(dú)在@implementation中定義方法,就不能該實(shí)現(xiàn)之外訪問該方法,,但事實(shí)并非如此,OC中不存在真正的私有方法,也無法將某個方法表示為私有方法,從而禁止其他方法調(diào)用它,這是OC動態(tài)本質(zhì)的副作用。
創(chuàng)建和使用對象
//創(chuàng)建對象,完成對象的聲明,內(nèi)存分配,初始化。
Student * stu = [[Student alloc]init];
//Student * stu = [Student new]; //與上一行代碼是等價的
//給Student對象的實(shí)例變量賦值。
stu ->name = @“A”;
stu ->hobby = @“\ “ 嗯。。。你懂的 \””;
方法
方法是類的功能代碼,寫在接口和實(shí)現(xiàn)中,方法名又稱為:selector(選擇器)
實(shí)例方法和類方法
減號開頭的方法是實(shí)例方法,需要實(shí)例化對象進(jìn)行調(diào)用,實(shí)例方法允許調(diào)用實(shí)例方法和實(shí)例變量。
加號開頭的方法是類方法,不需要實(shí)例化對象,直接通過類來調(diào)用,類方法的規(guī)則:
1.)類方法可以調(diào)用類方法。
2.)類方法不可以調(diào)用實(shí)例方法,但是類方法可以通過創(chuàng)建對象來訪問實(shí)例方法。
3.)類方法不可以使用實(shí)例變量,類方法可以使用self,因?yàn)閟elf不是實(shí)例變量。
4.)類方法作為消息,可以發(fā)送到類里面去,不能發(fā)送到對象里面去(實(shí)際上,就是可以通過類但是不能通過對象調(diào)用類方法)。
提示:消息傳遞模型(Message Passing)是OC語言的核心機(jī)制,OC中沒有方法調(diào)用這種說法,只有消息傳遞。
方法用來描述對象的行為,消息用于通知對象做什么,通過對象發(fā)送消息,對象接受消息后找對對象的方法調(diào)用運(yùn)行。
對象初始化
Student * stu = [[Student alloc]init];
對象初始化首先要給對象分配內(nèi)存空間,然后再將對象分配的內(nèi)存空間進(jìn)行初始化。
alloc方法:根據(jù)類中定義的實(shí)例變量分配分配內(nèi)存空間,并對內(nèi)存中的實(shí)例變量進(jìn)行初始化,整形初始化為0,浮點(diǎn)型初始化為0.0,字符型初始化為 “\0”,BOOL類型初始化為NO,指針類型初始化為nil。alloc方法返回對象的指針。
alloc方法只是用戶創(chuàng)建對象并初始化對象實(shí)例變量的默認(rèn)值,當(dāng)我們需要為對象實(shí)例變量的值設(shè)定,我們可以重寫init方法,來達(dá)到目的。
- (id)init
{
If (self = [super init]){
name = @“學(xué)生”;
age = 18;
}
return self;
}
一般不在init方法中創(chuàng)建復(fù)雜的對像和使用幾率比較小的對象。
此處init方法的返回類型是id數(shù)據(jù)類型,id數(shù)據(jù)類型是動態(tài)數(shù)據(jù)類型,可以指定任何類的對象,而不關(guān)心其具體類型,在運(yùn)行時檢測其具體類型,可以發(fā)送任何(存在的)消息。
便利初始化函數(shù)
在實(shí)際使用時,對象和對象的實(shí)例變量往往是不同的,所以我們需要在init方法調(diào)用時傳入個性化數(shù)據(jù)。使用自定義便利初始化函數(shù)。
在框架類庫中的一些類里面有一系列以init開頭的方法,這些方法就是便利初始化函數(shù)。例如:
[[NSString alloc] initwithFormat];
我們可以在類中定義自己的便利初始化函數(shù)
- (id)initWithName:(NSString *)aName andAge:(int)anAge
{
if (self = [super initWithName:aName]){
age = anAge;
}
return self;
}
- (id)initWithName:(NSString *)aName
{
If (self = [super init]){
name = [aName copy];
}
return self;
}
便利構(gòu)造器
使用便利初始化函數(shù)創(chuàng)建對象首先還是要調(diào)用alloc方法給對象分配內(nèi)存,然后再初始化對象,代碼還是略顯繁瑣。
Cocoa中有些方法通過將內(nèi)存分配過程和初始化過程組合起來完成對象創(chuàng)建,這些方法通常被稱為:便利構(gòu)造器
他們的命名通常以”className”開頭,類名首字母小寫開頭,并且都是類方法:例如:
+ (id)stringWithString:(const Char*)cString encoding(NSStringEncoding)enc;
+ (id)studentWithName:(NSString *) aName andAge:(int)aAge
{
Student * student = [[Student alloc] initWithName:aName andAge:aAge];
return student;
}
便利構(gòu)造器只不過是把對象創(chuàng)建分配內(nèi)存和調(diào)用便利初始化函數(shù)的代碼封裝起來,讓用戶使用起來更方便。
什么是封裝
將屬性及方法相結(jié)合,共同體現(xiàn)對象的特性,稱之為封裝。封裝可以做到隱藏內(nèi)部實(shí)現(xiàn),穩(wěn)定外部接口。