维基百科将“call super”归类为反模式,我真的不明白为什么。该模式在 Objective-C/cocoa 中经常使用;例如 init/dealloc、drawrect、awakefromnib 都需要你调用 super。我在这里误解了这个概念吗?
2 回答
正如它在文章中所说,调用作为反模式的超级方法是必要的,即超级类“期望”您重写该方法以使功能完整——但它这样做并没有明确表示这种期望。它还希望您调用超级实现。两者都是程序运行所必需的。
这是一种反模式,因为无法从代码中推断出程序员的意图。如果您的同事决定进行这项工作,他们将不知道您希望班级做什么,因此可能会遇到问题和/或烦恼。
因此,如果您希望方法的某些部分被覆盖,但其他东西需要保留在原地,建议使用模板方法模式,将所有不能替换的东西保留在一个(私有)方法中,然后调用另一个 - 完全独立 -必须实现它才能使程序工作(在某些语言中,它甚至不会编译)。这样,您可以确保重要的事情保持在它们必须在的位置,并且扩展该类的任何人都将确切地知道要做什么,而对其他实现细节却一无所知。
Objective-C 没有抽象或虚拟方法,但如果调用超级方法,您可以通过显式引发异常来达到相同的效果。这样,如果您的同事忘记覆盖该方法,程序将会崩溃 - 它会崩溃并显示他们可以理解的错误消息,这将使他们能够比一些不稳定的问题更快、更容易地理解和解决问题由于功能不完整,没有解释的行为。
问题的要点是:
..但是,语言本身可能无法强制执行此调用中规定的所有条件这一事实使其成为反模式。
所以作者对程序员不得不做一些他们认为语言应该为他们做的事情感到不满。
维基百科文章Call Super中提到的解决方案是:
解决这些问题的更好方法是使用模板方法模式,其中超类包含必须由子类实现的纯抽象方法,并让原始方法调用该方法
问题是 Objective-c 没有虚函数。它只有消息,因此您无法实现维基百科的建议。