我可以使用类类别覆盖已使用类别实现的方法吗?像这样:
1)原始方法
-(BOOL) method {
return true;
}
2)覆盖方法
-(BOOL) method {
NSLog(@"error?");
return true;
}
这行得通吗,还是非法的?
Answers:
从Apple文档:
尽管目前使用Objective-C语言可以使用类别来覆盖类继承的方法,甚至是在类接口中声明的方法,但强烈建议您不要这样做。类别不能替代子类。使用类别覆盖方法有几个明显的缺点:
当类别覆盖继承的方法时,该类别中的方法可以照常通过到的消息来调用继承的实现
super
。但是,如果类别覆盖了该类别的类中存在的方法,则无法调用原始实现。一个类别不能可靠地覆盖在同一类的另一个类别中声明的方法。
这个问题特别重要,因为许多可可类都是使用类别来实现的。您尝试覆盖的框架定义方法本身可能已经在一个类别中实现,因此未定义哪个实现优先。
某些类别方法的存在可能会导致所有框架的行为发生变化。例如,如果您
windowWillClose:
在NSObject的类别中覆盖了委托方法,则程序中的所有窗口委托都将使用类别方法进行响应。您的所有NSWindow实例的行为可能都会改变。您在框架类上添加的类别可能会导致行为的神秘变化并导致崩溃。
旧的文档链接已死;我能找到的最佳替代品是在这里:Apple Docs:
避免类别方法名称冲突
由于在类别中声明的方法已添加到现有类中,因此您需要非常小心方法名称。
如果在一个类别中声明的方法的名称与原始类中的方法的名称相同,或者在同一类(甚至是超类)的另一个类别中的方法的名称相同,则在使用哪种方法实现时未定义行为。运行。如果您在自己的类中使用类别,则不太可能出现问题,但是在使用类别向标准Cocoa或Cocoa Touch类中添加方法时,可能会引起问题。
苹果使用的是轻巧的触摸,但要点是一样的:您招致灾难,因为无法预测的行为是无声的。
重要的是要注意,类别也可以用于覆盖基类中的现有方法(例如,Car类的drive方法),但是绝对不要这样做。问题在于类别是扁平的组织结构。如果您覆盖Car + Maintenance.m中的现有方法,然后决定要使用其他类别再次更改其行为,那么Objective-C将无法知道要使用哪种实现。在这种情况下,子类化几乎总是一个更好的选择。