來(lái)源:
iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計(jì)方案
思路:
簡(jiǎn)單說(shuō)就是在init的時(shí)候檢查自己是否符合預(yù)先設(shè)計(jì)的子類的protocol,這就要求所有子類必須遵守這個(gè)protocol患久,所有針對(duì)父類的重載椅寺、覆蓋也都以這個(gè)protocol為準(zhǔn),protocol以外的方法不允許重載蒋失、覆蓋返帕。而在父類的代碼里,可以不必遵守這個(gè)protocol高镐,保持了未來(lái)維護(hù)的靈活性溉旋。
好處:
就是避免了父類寫空方法,同時(shí)也給子類帶上了緊箍咒:要想當(dāng)我的孩子嫉髓,就要遵守這些規(guī)矩观腊,不能亂來(lái)邑闲。業(yè)務(wù)方在實(shí)現(xiàn)子類的時(shí)候,就可以根據(jù)protocol中的方法去一一實(shí)現(xiàn)梧油,然后約定就比較好做了:不允許重載父類方法苫耸,只允許選擇實(shí)現(xiàn)或不實(shí)現(xiàn)protocol中的方法。
比如父類:BaseApiManeger 子類:ApiManager儡陨,ApiTestManager
在父類中的聲明協(xié)議 SuperMethodProtocol
,在 SuperMethodProtocol
中聲明需要重寫的方法褪子,指定為 @required
或 @optional
#import <Foundation/Foundation.h>
@protocol SuperMethodProtocol <NSObject>
@required
- (void)apiMethod;
@optional
- (void)chiledMethod;
@end
@interface BaseApiManeger : NSObject
// 聲明 child 的屬性,用于父類中調(diào)用子類中重載的方法
@property (nonatomic, weak) id<SuperMethodProtocol> child;
@end
父類 .m 文件實(shí)現(xiàn)
#import "BaseApiManeger.h"
@implementation BaseApiManeger
- (instancetype)init{
self = [super init];
if (self) {
if ([self conformsToProtocol:@protocol(SuperMethodProtocol)]) {
self.child = (id<SuperMethodProtocol>)self;
}
else{
NSAssert(NO, @"子類必須實(shí)現(xiàn) SuperMethodProtocol ");
}
}
return self;
}
/** 父類中調(diào)用子類中的方法 */
- (void)test{
[self.child apiMethod];
}
@end
子類實(shí)現(xiàn)
#import "BaseApiManeger.h"
// 遵守協(xié)議
@interface ApiManager : BaseApiManeger<SuperMethodProtocol>
@end
@implementation ApiManager
// 實(shí)現(xiàn)協(xié)議中的方法 -- 重載
- (void)apiMethod{
...
}
- (void)chiledMethod{
...
}
@end
如果子類沒有遵守協(xié)議骗村,則會(huì)報(bào)錯(cuò)
*** Assertion failure in -[ApiTestManager init], /Users/yons/Desktop/繼承重載/繼承重載/BaseApiManeger.m:21