類的三大特性(封裝,繼承,多態)

類有三大特性:繼承,封裝,多態:


封裝

封裝就是對類中的一些字段,方法進行保護,不被外界所訪問到,有一種權限的控制功能,Java中有四種訪問權限修飾符:

public,default,protected,private

訪問權限依次遞減,我們在定義類時,哪些字段和方法不想暴露出去,哪些字段和方法可以暴露,可以通過修飾符來完成,這就是封裝;

在OC語言中,使用@interface和@implementation來處理類。

@interface就好像暴露在外面的時鐘表面,像外界提供展示以及接口。@implementation就好像隱藏在時鐘內部的構造實現,把具體的實現封裝了起來。

(ps:@interface 中是成員變量,@implementation 是全局變量)

Car.h

#import

@interface?Car?:?NSObject{

//這個屬性就是對外進行保密的相當于private,所以我們需要在外部訪問的話,必須定義get/set方法

//默認的是private的,但是我們可以使用@public設置為public屬性的,那么在外部可以直接訪問:person->capcity?=?2.8;

//當然我們一般不這么使用,因為這會破壞封裝性,這種用法相當于C中的結構體中權限

//一共四種:@public,@protected,@private,@package,這個和Java中是相同的

@public

float?_capcity;?//油量屬性

}

-?(void)run:(float)t;

@end

這里我們可以看到,OC中也是有四種訪問權限修飾符:

@public、@protected、@private、@package

其中默認的修飾符是@private

但是這里要注意的是:OC中的方法是沒有修飾符的概念的,這個和Java有很大的區別,一般都是公開訪問的,即public,如果想讓一個方法不被外界訪問的話,只需要在.m文件中實現這個方法,不要在頭文件中進行定義,說白了就是:該方法有實現,沒定義,這樣外界在導入頭文件的時候,是沒有這個方法的,但是這個方法我們可以在自己的.m文件中進行使用。

開發過程中,考慮到安全性要求,一般不在成員變量名前面使用@public、@protected等關鍵字修飾,而是使用Set方法來為對象提供成員變量的值。在set方法的內部也可以對一些不合理的賦值進行篩選過濾。

命名規范:

(1)方法名必須以set開頭

(2)Set后面跟上成員變量的名稱,首字母大寫

(3)返回值一定是void

(4)一定要接收一個參數,而且參數類型需要和成員變量的類型一致

(5)形參名不能和成員變量名一樣(蘋果官方推薦成員變量名前加_以示區分)

繼承

繼承是類中的一個重要的特性,他的出現使得我們沒必要別寫重復的代碼,可重用性很高。當然OC中的繼承和Java中是一樣的,沒多大區別,這里在看一個例子吧:

父類:Car

Car.h

#import

@interface?Car?:?NSObject{

NSString?*_brand;

NSString?*_color;

}

-?(void)setBrand:(NSString?*)brand;

-?(void)setColor:(NSString?*)color;

-?(void)brake;

-?(void)quicken;

@end

Car.m

#import "Car.h"

//引入頭文件

@implementation?Car

-?(void)setBrand:(NSString?*)brand{

_brand?=?brand;

}

-?(void)setColor:(NSString?*)color{

_color?=?color;

}

-?(void)brake{

NSLog(@"剎車");

}

-?(void)quicken{

NSLog(@"加速");

}

@end

方法的實現

在來看一下子類:

Taxi.h

#import "Car.h"

@interface?Taxi?:?Car{

NSString?*_company;//所屬公司

}

//打印發票

-?(void)printTick;

@end

Taxi類繼承了父類Car, 需要導入父類的頭文件,在Taxi類中多了Car 的一個屬性和方法

Taxi.m

#import "Taxi.h"

@implementation?Taxi

-?(void)printTick{

[super?brake];

[self?brake];

NSLog(@"%@出租車打印了發票,公司為:%@,顏色為:%@",_brand,_company,_color);

}

@end

對方法的實現,看到實現文件中是不需要導入父類Car的頭文件的,因為可以認為,Taxi.h頭文件中已經包含了Car的頭文件了。

而且,這里可以使用super關鍵字來調用父類的方法,也是可以用self關鍵字來調用,這里看到其實這兩種方式調用的效果是一樣的,當子類重新實現brake方法的時候(Java中的重寫概念)。

那么這時候super關鍵字調用的還是父類的方法,而self調用的就是重寫之后的brake方法了。同樣,我們也是可以使用父類中的屬性。

附上一句理解的話就是,老爸就是超級的,自己的就是self

Train.h

#import "Car.h"

//火車類繼承Car

@interface?Train?:?Car{

float?_maxWeight;//最大載貨量

}

//覆蓋父類的方法brake

//優先調用子類的方法

-?(void)brake;

-?(void)unload;

@end

自己定義了一個brake方法,這時候就會覆蓋父類中的brake方法了。

Train.h

#import "Train.h"

@implementation Train

-?(void)brake{

[super?brake];

NSLog(@"Train類中的brake方法");

}

-?(void)unload{

[super?brake];//調用父類的方法

[self?brake];//也是可以的

NSLog(@"%@的火車卸貨了,載貨量:%.2f,車的顏色:%@",_brand,_maxWeight,_color);

}

@end

可以看到,在brake方法中調用一下父類的brake方法,然后在實現自己的邏輯代碼。


多態

大學上了三年多的課,無時無刻都在聽到多態這個詞,但是以前感覺自己不認真,也沒怎么重視這個東西,其實這東西一直很重要這是真的。

Printer.h

#import

@interface?Printer?:?NSObject

-?(void)?print;

@end

Printer.m

#import "Printer.h"

@implementation?Printer

-?(void)print{

NSLog(@"打印機打印紙張");

}

@end

PrinterCorl.h

#import "PrinterCor.h"

//修改父類的打印行為

@interface?ColorPrinter?:?Printer

-?(void)print;

@end

PrinterCorl.m

#import "PrinterCorl.h"

@implementation ColorPrinter

-?(void)print{

NSLog(@"彩印");

}

@end

BlackPrinter.h

#import "BlackPrinter.h"

@implementation?BlackPrinter

-?(void)print{

NSLog(@"黑白打印機");

}

@end

這里我們在定義一個Person類,用來操作具體的打印機

Person.h

@implementation Person

- (void)doPrint:(Printer *)printer{

}

@end

Person.m

#import "Person.h"

@implementation?Person

/*

-?(void)?printWithColor:(ColorPrinter?*)PrintCorl{

[colorPrint?print];

}

-?(void)?printWithBlack:(BlackPrinter?*)blackPrint{

[blackPrint?print];

}

*/

-?(void)?doPrint:(Printer?*)printer{

[printer?print];

}

@end

main.m

#import "Person.h"

#import?"BlackPrinter.h"

#import?"PrinterCorl.h"

int?main(int?argc,?const?charchar?*?argv[])?{

@autoreleasepool?{

Person?*person?=[[Person?alloc]?init];

PrinterCorl *colorPrint?=?[[ColorPrinter?alloc]?init];

BlackPrinter?*blackPrint?=?[[BlackPrinter?alloc]?init];

//多態的定義

/*

Printer?*p1?=?[[ColorPrinter?alloc]?init];

Printer?*p2?=?[[BlackPrinter?alloc]?init];

[person?doPrint:p1];

[person?doPrint:p2];

*/

//通過控制臺輸入的命令來控制使用哪個打印機

int?cmd;

do{

scanf("%d",&cmd);

if(cmd?==?1){

[person?doPrint:colorPrint];

}else?if(cmd?==?2){

[person?doPrint:blackPrint];

}

}while?(1);

}

return?0;

}

下面就來詳細講解一下多態的好處

上面的例子是一個彩色打印機和黑白打印機這兩種打印機,然后Person類中有一個操作打印的方法,當然這個方法是需要打印機對象的,如果不用多態機制實現的話(Person.h中注釋的代碼部分),就是給兩種打印機單獨定義個操作的方法,然后在Person.m(代碼中注釋的部分)中用具體的打印機對象進行操作,在main.m文件中,我們看到,當Person需要使用哪個打印機的時候,就去調用指定的方法:


這種設計就不好了,為什么呢?假如現在又有一種打印機,那么還需要在Person.h中定義一種操作這種打印機的方法,那么后續如果在添加新的打印機呢?還在添加方法嗎?那么Person.h文件就會變得很臃腫。所以這時候多態就體現到好處了,使用父類類型,在Person.h中定義一個方法就可以了:

-?(void)?doPrint:(Printer?*)printer;

這里看到了,這個方法的參數類型就是父類的類型,這就是多態,定義類型為父類類型,實際類型為子類類型

-?(void)?doPrint:(Printer?*)printer{

[printer?print];

}

這里調用print方法,就是傳遞進來的實際類型的print方法。

Printer?*p1?=?[[ColorPrinter?alloc]?init];

Printer?*p2?=?[[BlackPrinter?alloc]?init];

[person?doPrint:p1];

[person?doPrint:p2];

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容