我知道不应该使用类别来覆盖它们正在扩展的类中的方法。但是,下面的场景呢。
考虑课程:
Base.h
#import <Foundation/NSObject.h>
@interface Base: NSObject { NSNumber *n; }
@end
Derived.h
#import "Base.h"
@interface Derived: Base { NSString *s; }
@end
有类别:
基础+ Serialize.h
#import "Base.h"
@interface Base (Serialize)
- (NSString*)serialize;
@end
基础+ Serialize.m
#import "Base+Serialize.h"
@implementation Base (Serialize)
- (NSString*)serialize
{
return [NSString stringWithFormat:@"%@", n];
}
@end
派生+ Serialize.h
#import "Derived.h"
#import "Base+Serialize.h"
@interface Derived (Serialize)
- (NSString*)serialize;
@end
派生+ Serialize.m
#import "Derived+Serialize.h"
@implementation Derived (Serialize)
- (NSString*)serialize
{
return [NSString stringWithFormat:@"%@, %@", s, [super serialize]];
}
@end
显然,这是一个人为/简化的例子。但它很适合展示我想做的事情。本质上,我想为继承层次结构中的多个类提供附加功能。
这是否安全/有效地使用类别?任何陷阱?
答案 0 :(得分:1)
这似乎不是一个非常好的对象模型。 Base.h和Derived.h看起来很好。如何使用Protocol来定义serialize:方法而不是类别?那会更清洁一些。 Base.h表示它将实现协议,Derived可以根据需要覆盖该方法。
答案 1 :(得分:1)
这是使用类别的可接受方式。类别确实会将消息添加到类中,因此消息将像任何其他消息一样工作。这包括继承。
也许有一点需要注意的是,你可能遇到名称冲突。我不知道运行时如何处理它们,但如果两个类别提供相同的消息,则可能会出现意外行为,因为您预期的消息未被调用。话虽这么说,你可能只想要一个比serialize
更有特色的名字,除非你需要那个名字(例如你有一个非正式的协议)。