Objective-c 實(shí)現(xiàn)“多繼承”

假設(shè)C類要同時(shí)繼承A類和B類,則稱之為多繼承补箍。而Objective-C不支持多繼承卒蘸,由于消息機(jī)制名字查找發(fā)生在運(yùn)行時(shí)而非編譯時(shí)校辩,很難解決多個(gè)基類可能導(dǎo)致的二義性問(wèn)題。不過(guò)其實(shí) Objective-C 也無(wú)需支持多繼承哥纫,我們可以找到如下幾種間接實(shí)現(xiàn)多繼承目的的方法:

  • 通過(guò)組合實(shí)現(xiàn)“多繼承”

  • 通過(guò)協(xié)議實(shí)現(xiàn)“多繼承”

  • 通過(guò)category實(shí)現(xiàn)“單繼承”(大部分網(wǎng)上文章將此方法誤解成“多繼承”)

通過(guò)這幾種方法實(shí)現(xiàn)的“多繼承”霉旗,與真實(shí)的多繼承還是有明顯的區(qū)別的,因此這里給所有的多繼承加上雙引號(hào)蛀骇。

通過(guò)組合實(shí)現(xiàn)“多繼承”

//定義ClassA以及其methodA
@interface ClassA : NSObject {
}
-(void)methodA;
@end

//定義ClassB以及其methodB
@interface ClassB : NSObject {
}
-(void)methodB;
@end

//定義ClassC以及其需要的methodA厌秒,methodB
@interface ClassC : NSObject {
ClassA *a;
ClassB *b;
}
-(id)init;
-(void)methodA;
-(void)methodB;
@end

//注意在ClassC的實(shí)現(xiàn)
@implementation  ClassC
-(id)init{
a=[[ClassA alloc] init];
b=[[ClassB alloc] init];
}

-(void)methodA{
[a methodA];
}

-(void)methodB{
[b methodB];
}

通過(guò)協(xié)議實(shí)現(xiàn)“多繼承”
雖然OC在語(yǔ)法上禁止類使用多繼承,但是卻可以用協(xié)議來(lái)實(shí)現(xiàn)多繼承擅憔。協(xié)議只能提供接口鸵闪,而沒(méi)有提供實(shí)現(xiàn)方式,如果只是想多繼承基類的接口暑诸,那么遵守多協(xié)議無(wú)疑是最好的方法蚌讼。
此方法缺點(diǎn)比較明顯:需要修改兩個(gè)父類,同時(shí)并不能調(diào)用兩個(gè)父類的原生方法个榕,需要在子類中實(shí)現(xiàn)方法篡石。

1、定義ClassA 以及 ClassAProtocol
@interface ClassA : NSObject
@end

@protocol ClassAProtocol <NSObject>
-(void)a;
@end
 
2西采、定義ClassB 以及 ClassBProtocol
@interface ClassB : NSObject
@end

@protocol ClassBProtocol <NSObject>
-(void)b;
@end

3凰萨、定義ClassC
@interface ClassC : NSObject
-(void)c;
@end

//ClassC定義以及實(shí)現(xiàn)
#import <Foundation/Foundation.h>
#import "ClassC.h"
#import "ClassA.h"
#import "ClassB.h"

@interface ClassC:NSObject< ClassAProtocol, ClassBProtocol>
-(void)c;
@end


#import "ClassC.h"
@implement ClassC
-(void)a
{
}

-(void)b
{
}

-(void)c
{
}
@end

通過(guò)類別實(shí)現(xiàn)“單繼承”
首先摘錄一段網(wǎng)上對(duì)類的描述:
? 使用類別就是為了能夠?yàn)楝F(xiàn)有類添加新的方法,不用繼承該現(xiàn)有類,就可使用現(xiàn)有類的對(duì)象調(diào)用添加的方法了胖眷。
? 類別可以使類的實(shí)現(xiàn)分散在多個(gè)文件中.
? 類別中不能有變量武通,類別中沒(méi)有放變量的位置.
? 如果類中的方法和類別中的方法名稱相同,這將造成沖突珊搀,類別的方法將完全取代類的方法冶忱。
? 同一個(gè)類的不同類別聲明了相同的方法,這將導(dǎo)致不穩(wěn)定境析,哪個(gè)方法會(huì)被調(diào)用是不確定的.
網(wǎng)上很多介紹這種方法的文章囚枪,都給出了一個(gè)通過(guò)類別實(shí)現(xiàn)“單繼承”的例子,而非“多繼承”的例子簿晓,但卻得出實(shí)現(xiàn)了“多繼承”的結(jié)論眶拉,往往使初學(xué)者一知半解云里霧里。通過(guò)類別可以簡(jiǎn)單實(shí)現(xiàn)類似“單繼承”功能憔儿,要實(shí)現(xiàn)“多繼承”則相對(duì)復(fù)雜一些忆植,可以通過(guò)一個(gè)新類包含多個(gè)類別的方法來(lái)實(shí)現(xiàn)“多繼承”,并不推薦使用谒臼。這里也僅給出一個(gè)通過(guò)類別實(shí)現(xiàn)“單繼承”的例子朝刊,同時(shí)在繼承的“子類”中增加了兩個(gè)函數(shù)。

// 為上例中的A類增加一個(gè)方法(類似繼承)

// A+C.h
#import "A.h"
@interface A (C) //類別的聲明
- (void)setAddr:(NSString *)addr;
- (NSString *)addr;
@end

//
//  A+C.m  
//    
#import "A+C.h"  
#import <objc/runtime.h>  
  
const char *Addr = "NSString *";  
@implementation A (C)  //注意此處類別的格式
  
- (void)setAddr:(NSString *)addr
{
    objc_setAssociatedObject(self, Addr, addr, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)addr
{
    NSString *addr = objc_getAssociatedObject(self, Addr);
    return addr;
}

@end
  
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蜈缤,一起剝皮案震驚了整個(gè)濱河市拾氓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌底哥,老刑警劉巖咙鞍,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異趾徽,居然都是意外死亡续滋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門孵奶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)疲酌,“玉大人,你說(shuō)我怎么就攤上這事了袁±士遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵载绿,是天一觀的道長(zhǎng)粥诫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)崭庸,這世上最難降的妖魔是什么怀浆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任劝堪,我火速辦了婚禮,結(jié)果婚禮上揉稚,老公的妹妹穿的比我還像新娘。我一直安慰自己熬粗,他們只是感情好搀玖,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著驻呐,像睡著了一般灌诅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上含末,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天猜拾,我揣著相機(jī)與錄音,去河邊找鬼佣盒。 笑死挎袜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肥惭。 我是一名探鬼主播盯仪,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蜜葱!你這毒婦竟也來(lái)了全景?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤牵囤,失蹤者是張志新(化名)和其女友劉穎爸黄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體揭鳞,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炕贵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汹桦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲁驶。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖舞骆,靈堂內(nèi)的尸體忽然破棺而出钥弯,到底是詐尸還是另有隱情,我是刑警寧澤督禽,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布脆霎,位于F島的核電站,受9級(jí)特大地震影響狈惫,放射性物質(zhì)發(fā)生泄漏睛蛛。R本人自食惡果不足惜鹦马,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忆肾。 院中可真熱鬧荸频,春花似錦、人聲如沸客冈。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)场仲。三九已至和悦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渠缕,已是汗流浹背鸽素。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亦鳞,地道東北人馍忽。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像燕差,于是被迫代替她去往敵國(guó)和親舵匾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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