这种继承和协议的组合是否正确?

时间:2014-08-01 08:22:24

标签: objective-c inheritance protocols

在我希望将一个类打算成为基类的场景中,考虑到需要实现其子子句指向的某些基本行为,我想出了这个:

协议

@protocol TheProtocol

@required

- (NSString *)someProperty;
- (void)someMethod:(NSString *)parameter;

@end

基本视图控制器

@interface BaseViewController : UIViewController
@end

@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSAssert([self conformsToProtocol:@protocol(TheProtocol)], @"This view controller has to conform to TheProtocol.");
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    BaseViewController<TheProtocol> *castedController = (BaseViewController<TheProtocol> *)self;

    NSString *someProperty = [castedController someProperty];
    NSLog(@"%@", someProperty);        

    [castedController someMethod:@"Hello subclass!"];
}

@end

实施协议的控制器示例

@interface Subclass1ViewController : BaseViewController <TheProtocol>
@end

@implementation Subclass1ViewController

#pragma mark - TheProtocol

- (NSString *)someProperty {

    return @"Subclass1";
}

- (void)someMethod:(NSString *)parameter {

    NSLog(@"%@", parameter);
}

@end

这种模式是否正确?我有很多顾虑......另一种选择是创建受保护的类别而不是协议。

1 个答案:

答案 0 :(得分:1)

你的模式是对的。

这里只是与你的想法完全相似的解决方案,但我个人会在我的项目中为了达到同样的目的而这样做 - 所以我不需要在课堂上投射BaseClass的实例,因为在我的想法中,基类基本上符合基本的DemandedProtocol,但在每个必需的方法中抛出一个运行时异常,该方法尚未在子集中被覆盖但是试图被调用。

注意:这并不比你的更差或更好,但不同,任何人都可以将其用于教育目的。

DemandedProtocol.h

@protocol DemandedProtocol <NSObject>

@required

- (NSString *)someString;
- (void)setSomething:(id)something;

@optional

- (NSInteger)someInteger;

@end

BaseClass.h

#import "DemandedProtocol.h"

#define ThrowOverrideIsMissingException @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%s has to be overridden in subset.", __func__] userInfo:nil]

@interface BaseClass : NSObject <DemandedProtocol> {

}

@end

BaseClass.m

#import "BaseClass.h"

@implementation BaseClass

#pragma mark - <DemandedProtocol>

- (NSString *)someString {
    ThrowOverrideIsMissingException;
}

- (void)setSomething:(id)something {
    ThrowOverrideIsMissingException;
}

@end