Objective C - 类别和继承 - 将方法添加到base并将覆盖添加到派生类

时间:2012-02-23 15:56:09

标签: objective-c inheritance categories

我知道不应该使用类别来覆盖它们正在扩展的类中的方法。但是,下面的场景呢。

考虑课程:

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

显然,这是一个人为/简化的例子。但它很适合展示我想做的事情。本质上,我想为继承层次结构中的多个类提供附加功能。

这是否安全/有效地使用类别?任何陷阱?

2 个答案:

答案 0 :(得分:1)

这似乎不是一个非常好的对象模型。 Base.h和Derived.h看起来很好。如何使用Protocol来定义serialize:方法而不是类别?那会更清洁一些。 Base.h表示它将实现协议,Derived可以根据需要覆盖该方法。

答案 1 :(得分:1)

这是使用类别的可接受方式。类别确实会将消息添加到类中,因此消息将像任何其他消息一样工作。这包括继承。

也许有一点需要注意的是,你可能遇到名称冲突。我不知道运行时如何处理它们,但如果两个类别提供相同的消息,则可能会出现意外行为,因为您预期的消息未被调用。话虽这么说,你可能只想要一个比serialize更有特色的名字,除非你需要那个名字(例如你有一个非正式的协议)。