【问题标题】:how to block a superclass method to be called to a subclass如何阻止将超类方法调用到子类
【发布时间】:2008-11-27 15:50:08
【问题描述】:

我正在使用子类扩展类的功能,并且我正在做一些肮脏的事情,使超类方法在子类的上下文中变得危险(应用程序将挂在循环中)。我知道这不是一个天才的想法,但我正在寻找低调的果实,现在它可以节省我一些时间。哦,这是一项肮脏的工作,但总得有人去做。

底线,我需要从外部阻止该方法,或者在直接调用超类时抛出异常。 (但我仍然在子类中使用它,除非要小心)。

最好的方法是什么?

更新---

所以这就是我的目标。我不是自我回答,因为 Boaz 的回答提到了多种有效的方法来做到这一点,这正是适合我的方式。在子类中,我重写了这样的方法:

- (int)dangerousMethod
{
  [NSException raise:@"Danger!" format:@"Do not call send this method directly to this subclass"];
  return nil;
}

我将此标记为已回答,但显然这并不意味着它已关闭,欢迎提供进一步的建议。

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    只要在你的子类中重新实现 unsafe 方法,让它什么都不做,或者抛出异常,或者重新实现它是安全的,只要新实现不调用 unsafe 超类方法。

    对于这里的 C++ 工作人员:Objective C 不允许您将方法标记为私有。您可以使用其类别系统将接口拆分为单独的文件(从而隐藏“私有”文件),但类上的所有方法都是公共的。

    【讨论】:

    • 我不确定这是否可行。如果您按照您所说的进行操作,然后从子类调用位于超类中的某个“安全”函数,该函数又称为“不安全”函数,那么子类中的无操作/异常方法将由于多态性而被调用。
    • 听起来不错。正如你所说,只要我从不从超类调用不安全的超类方法。对于远非完美的实践来说,这是一个不完美的解决方案,但它可能是我能得到的最好的解决方案。
    【解决方案2】:

    您可以在子类的.h 文件中覆盖您想要阻止的任何方法。您可以通过将以下内容放入您的 .h 文件中来使 dangerousMethod 不可用。

    - (int)dangerousMethod __attribute__((unavailable("message")));
    

    这将使使用您的子类的任何人都无法使用dangerousMethod 方法。

    要防止其他代码使用此方法的超类版本,您可以通过将其放入您的.m 文件来进一步限制。

    - (int)dangerousMethod 
    {
        return nil;     
    }
    

    【讨论】:

    • 我不知道 __attribute__(()),谢谢! __attribute__((unavailable("message"))) 对我不起作用(我收到“错误:为‘不可用’属性指定的参数数量错误”)但 __attribute__((unavailable)) 对我有用。
    • 您可以使用__unavailable 代替__attribute__((unavailable("message")))
    • __unavailable(或简写)不适用于继承的方法。我试过了,结果很伤心。这看起来是最明智的处理方式,但目前还行不通。
    【解决方案3】:

    注意:我是 ObjC/Cocoa 新人:

    @implementation MyClass
    -(void)myMethod:(NSString *)txt{
        if([self class] != [MyClass class]) return;
        NSLog(@"Hello");
    }
    @end
    

    彼得

    【讨论】:

    • 嘿,彼得,这可以完成这项工作,除了.. 如果我有另一个子类确实需要该方法怎么办?
    【解决方案4】:

    本文介绍了如何创建private variables in Objective C。它们并不是真正私有的,但是根据我的阅读,如果您尝试从子类中调用它们,编译器会抛出警告。

    【讨论】:

    • 嘿 Kibbee,我知道那个程序。正如你所说,它不会使它们成为私有的。它只会引发警告。意味着您仍然可以通过调用这些方法来编译代码。为了正确起见,objc 中的变量可以是私有的,方法不能。
    【解决方案5】:

    如果您将超类中的方法创建为“私有”,则子类无法调用它们。我不熟悉Objective C,但我见过的所有其他面向对象的语言都有“私有”限定符。

    【讨论】:

    • 忘了提,我需要在超类上公开该方法。我会编辑。
    • 为什么需要在超类中公开?如果是回调方法,则创建一个适配器类来接收回调并将适配器隐藏为私有对象。
    • 抱歉,objc 中实际上没有公共/私有方法。适配器的概念很有趣,我从未听说过。但我个人不想让这更复杂,我宁愿抛出异常。
    • 我喜欢为一个曾经是正确的答案而被修改,直到发布者改变了问题。
    • Kibbee,对不起,我的问题问得不好,我已尽力通过编辑来解决它,但我认为这里没有必要,因为它与您的负分无关.一直都是关于 objc 的,而 objc 没有私有方法。
    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多