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

假設C類要同時繼承A類和B類,則稱之為多繼承。而Objective-C不支持多繼承,由于消息機制名字查找發(fā)生在運行時而非編譯時,很難解決多個基類可能導致的二義性問題。不過其實 Objective-C 也無需支持多繼承,我們可以找到如下幾種間接實現(xiàn)多繼承目的的方法:

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

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

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

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

通過組合實現(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的實現(xiàn)
@implementation  ClassC
-(id)init{
a=[[ClassA alloc] init];
b=[[ClassB alloc] init];
}

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

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

通過協(xié)議實現(xiàn)“多繼承”
雖然OC在語法上禁止類使用多繼承,但是卻可以用協(xié)議來實現(xiàn)多繼承。協(xié)議只能提供接口,而沒有提供實現(xiàn)方式,如果只是想多繼承基類的接口,那么遵守多協(xié)議無疑是最好的方法。
此方法缺點比較明顯:需要修改兩個父類,同時并不能調(diào)用兩個父類的原生方法,需要在子類中實現(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定義以及實現(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

通過類別實現(xiàn)“單繼承”
首先摘錄一段網(wǎng)上對類的描述:
? 使用類別就是為了能夠為現(xiàn)有類添加新的方法,不用繼承該現(xiàn)有類,就可使用現(xiàn)有類的對象調(diào)用添加的方法了。
? 類別可以使類的實現(xiàn)分散在多個文件中.
? 類別中不能有變量,類別中沒有放變量的位置.
? 如果類中的方法和類別中的方法名稱相同,這將造成沖突,類別的方法將完全取代類的方法。
? 同一個類的不同類別聲明了相同的方法,這將導致不穩(wěn)定,哪個方法會被調(diào)用是不確定的.
網(wǎng)上很多介紹這種方法的文章,都給出了一個通過類別實現(xiàn)“單繼承”的例子,而非“多繼承”的例子,但卻得出實現(xiàn)了“多繼承”的結論,往往使初學者一知半解云里霧里。通過類別可以簡單實現(xiàn)類似“單繼承”功能,要實現(xiàn)“多繼承”則相對復雜一些,可以通過一個新類包含多個類別的方法來實現(xiàn)“多繼承”,并不推薦使用。這里也僅給出一個通過類別實現(xiàn)“單繼承”的例子,同時在繼承的“子類”中增加了兩個函數(shù)。

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

// 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
  
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容