我写了一个示例代码策略设计模式。
@protocol MyProtocol
- (void)execute1;
@end
@interface BaseClass : NSObject
@property(nonatomic, assign) NSInteger commonValue;
- (void)commonCalculator;
@end
@interface DogClass : BaseClass <MyProtocol>
@end
@interface CatClass : BaseClass <MyProtocol>
@end
另外,我想创建一个BaseClass来实现一个通用的逻辑。
但是,无法从 MyProtocol 类型访问 BaseClass。
例如
- (void)foo {
NSInteger type = 0;
id<MyProtocol> obj = [self simpleFactory:type];
[obj execute1]; // It works!!
// I'd like the following code. However compile error occurs.
[obj commonCalculator]; // error
obj.commonValue = 10; // error
// I don't want the following code.
if (type == 0 ) {
[(DogClass *)obj commonCalculator];
((DogClass *)obj).commonValue = 10;
} else {
[(CatClass *)obj commonCalculator];
((CatClass *)obj).commonValue = 10;
}
}
- (id<MyProtocol>)simpleFactory:(NSInteger)type {
if (type == 0) {
return [[DogClass alloc] init];
} else {
return [[CatClass alloc] init];
}
}
有没有办法在使用策略模式的同时在 BaseClass 中使用通用代码?
最佳答案
如果BaseClass
实现 <MyProtocol>
的默认行为, 然后 BaseClass
应采用并实现<MyProtocol>
.
@interface BaseClass : NSObject <MyProtocol>
@property(nonatomic, assign) NSInteger commonValue;
- (void)commonCalculator;
@end
然后子类将继承该协议(protocol):
@interface DogClass : BaseClass
...
@interface CatClass : BaseClass
...
好消息是子类可以调用[super execute1]
如果您尝试使用或传递 BaseClass
的实例,编译器不会提示作为id<MyProtocol>
.
现在,如果出于某种无法解释的原因,您必须分离 BaseClass <MyProtocol>
的父类(super class)实现的代码。到它自己的模块中,可以通过创建 BaseClass
的类别来做到这一点在那里采用并实现您的默认实现:
@interface BaseClass (MyProtocolDefaults) <MyProtocol>
@end
...
@implementation BaseClass (MyProtocolDefaults)
- (void)execute1
{
...
}
@end
如果你这样做,我仍然建议你仍然不要在你的子类中重新采用协议(protocol)(即使它是完全合法的),而是通过导入 BaseClass
来“拾取”协议(protocol)。类别:
#import "BaseClass.h"
#import "BaseClass+MyProtocolDefaults.h"
@interface DogClass : BaseClass
// this class adopts <MyProtocol> indirectly through the BaseClass category
关于ios - Objective-C 中的策略模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52080822/