【问题标题】:Calling child overrided method from parent从父级调用子级覆盖的方法
【发布时间】:2013-02-25 12:17:47
【问题描述】:

我很难找到在 Objective-C 中实现类似于抽象类的方法。

我实际上并不关心限制使用我的基类而不继承它,我想要的是: 我想要拥有类似- (void)makeRequest 的方法的A 类(父/基/抽象),我想在B、C、D 等类中对其进行子类化,并拥有从类'A 调用的- (id)getCachedResult 等方法方法。所以基本上我希望 A 类实现一些基本逻辑,并且我希望它的子类修改这个基本逻辑的一些细节和部分。

听起来很琐碎,但我无法确定在 Objective-C 中实现这种模式的方法。

更新:

这是我想要做的:

@interface A : NSObject

- (void)makeRequest;
- (NSString *)resultKey;

@property (strong) NSMutableDictionary * result;

@end

@implementation A

- (void)makeRequest
{
    self.result[self.resultKey] = @"Result";
}

- (NSString *)resultKey
{
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:[NSString stringWithFormat:@"%@ should be overrided in subclass", NSStringFromSelector(_cmd)]
                                 userInfo:nil];
    return nil;
}

@end

/////////////////////////////

@interface B : A

@end

@implementation B

- (NSString *)resultKey
{
    return @"key";
}

@end

当我创建 B 类的实例并尝试调用它的方法 - (void)makeRequest 时,我遇到了异常,这很明显。我想要的是一种为相同目的正确设计我的课程的方法。

【问题讨论】:

  • 这很简单。这是子类化的基本概念。你的问题到底出在哪里?您应该提供一些具体的代码示例并用它来描述问题。当你做的每件事都正确时——而且犯错的机会不多——那么它应该按照你描述的方式工作。
  • @HermannKlecker,好的,我会更新我的问题,更具体地说明我在哪里遇到问题。
  • 你应该在B的界面声明resultKey
  • 我不明白为什么resultKeyA?被调用,而不是 resultKeyB。到目前为止,一切都很好。您能否在创建B 实例并调用其makeRequest 的位置添加该代码?
  • 您实际上得到了什么例外?您正在使用的一个或一个可能是 result 未初始化或访问的密钥不存在的结果。顺便说一句,结果是一个数组,而不是字典。您应该使用数字索引。另外,您应该使用“老式” objectAtIndex: 方法来访问索引。但是我假设,如果你想要键值对,最好使用 NSDictionary。在任何情况下,您的数组或字典都需要初始化和分配,当然还需要填充您要获取的数据。

标签: objective-c


【解决方案1】:

根据要求:您应该在 B 的界面中声明resultKey。 :-)

【讨论】:

  • 可能是风格问题。但是接口中的方法声明对运行时行为没有影响。不管解决了什么问题,都不是这样。
  • @ChrisDevereux:我不同意。在运行时,消息通过请求的选择器(不是方法)发送到“最低”(在类层次结构中)对象。编译器从接口生成选择器。它也可以在运行时完成,但这必须明确地完成。在 OP 的问题中,不知道 B 类的选择器,因此调用了超类的方法。
  • “当消息被发送到一个对象时,消息传递函数跟随对象的 isa 指针指向它在调度表中查找方法选择器的类结构”。 B 的 isa 指针的一个实例指向 B。实现该方法足以让调度表返回 B 对resultKey 的实现。这不需要在@interface 中声明。所以改变 B 的接口声明对 B 的运行时行为没有影响。
  • @Matthias 选择器不与任何实现耦合,当然也不会在编译时绑定到任何类的实现...
猜你喜欢
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-01
  • 2022-12-18
  • 2017-11-11
  • 2021-05-17
相关资源
最近更新 更多