【问题标题】:Can subclass override non-public methods子类可以覆盖非公共方法
【发布时间】:2013-06-04 09:02:42
【问题描述】:

我有两个班级:BatchDownloaderSpeechDownlader

BatchDownloader 是基类,SpeechDownloader 继承了它。

BatchDownloader中,每当下载一个文件时,都会调用-(void)downloadComplete:task

但是在SpeechDownloader,我也想在downloadComplete:task发布通知。

我可以在SpeechDownloader的实现中写同名的方法吗?还是有更好的方法?

谢谢。

附言我不想公开-(void)downloadComplete:task,因为它只能被自己调用。

【问题讨论】:

  • 我不明白您发布来自 Speechdownloader 的通知是什么意思。你想做什么?这可能会告诉我们有关您的问题的更多信息。
  • 我发现这是最好的答案。轻松、简单、安全:stackoverflow.com/questions/16678463/…

标签: objective-c oop


【解决方案1】:

如果您在子类中实现的方法与超类中的私有方法同名,则您的子类方法在子类的实例上调用。

即,如果您像这样在超类中实现一个方法,而不在任何地方声明它:

@implementation classA

- (void)doSomething {
    NSLog("a");
}

然后,在你的子类实现中,实现一个同名的方法:

@implementation subclassOfA

- (void)doSomething {
    NSLog("b");
}

当您在子类的实例上调用 doSomething 时,将调用子类实现 而不是超类实现,因此此示例中的代码将导致“b”被打印到控制台。

但是,如果您还想访问该方法的超类实现,则可以使用:

- (void)doSomething {
    [super doSomething];
    NSLog("b");
}

这也将调用超类实现。如果您收到编译错误(由于方法是私有的并且 super 似乎没有实现它),您可以使用 [super performSelector:@selector(doSomething)] 来代替做完全相同的事情。

这是因为 Objective-C 运行时查找方法调用的方式。由于这些方法具有完全相同的方法签名(相同的名称、返回类型和参数 [none]),因此它们被认为是相等的,并且运行时总是在查看超类之前检查对象的类,因此它会找到子类的方法实现首先。

另外,这意味着你可以这样做:

classA *test = [subclassOfA new];
[test doSomething];

而且,令人惊讶的是,控制台将打印“b”(如果您也调用了super 实现,则为“a b”)。

【讨论】:

  • 感谢您的精彩插图,问题已解决。似乎拼写错误有时会成为问题,对吧?
  • 显然,因为这意味着方法名称不同,因此就运行时而言,方法签名也不同,因为它没有拼写检查器。
【解决方案2】:

如果您使用相同的方法签名实现该方法,它将被称为相信您的实现,无论是否公开。

【讨论】:

    猜你喜欢
    • 2015-08-26
    • 2012-10-09
    • 2010-12-30
    • 2019-02-13
    • 2011-05-11
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    相关资源
    最近更新 更多