Objective-C 类别与 Mixins 的比较
Objective-C 类别的概念是否与 mixin 的概念相似? 如果是这样:有什么相似之处? 不:有什么区别?
Is the concept of the Objective-C categories in anyway similar to the concept of mixins? If so: what are the similarities? In not: what are the differences?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
据我所知:
Mixins
类别
To the best of my understanding:
Mixins
Categories
需要明确的是,答案是否定的——它们不一样。
John Calsbeek 在接受的答案中概述了这些差异,但我想说,关键的区别是 mixin 可以在不同的类中使用,而类别总是扩展一个类 - 它们在定义中声明。
这是关键的区别,因为这意味着这两个功能的用例完全不同。 另一种看待它的方式是,如果您从 Ruby 转向 Objective-C 并且缺少 mixin,那么您将不会发现类别的任何乐趣。
mixins 的用例是您有一些代码(方法和实例变量),您希望在没有公共超类的多个类中重用它们。 你不能用类别来做到这一点。
Mixins 实际上是 Objective-C 中找不到的类型的“多重继承”。 Objective-C 中最接近的东西是协议,就像 Java 最接近的东西是接口一样,但它们既没有实例变量,也没有方法体(在 Objective-C 或 java 中)。 因此,您通常只能创建辅助类或将代码放入超类中。
Objective-C 类别的用例是您想要向现有类添加方法 - 甚至是系统或库类。
我想说 mixins 更强大,但由于这是苹果与橘子的比较,所以毫无意义。
准确地说:
Ruby 相当于类别,只需重新打开要扩展的类并扩展它。 (您可以在 Ruby 中的任何位置执行此操作,它实际上与类别相同)
我不确定与 Mixins 等效的 Objective-c 是什么 - 有人吗?
[更新] 再搜索一下,Objective-C 中并没有 Mixins 的等价物,但有进取心的 Vladimir Mitrovic 创建了一个可以有效实现这一目标的库。 https://github.com/vl4dimir/ObjectiveMixin
对于是否使用它,我有两种想法:有时如果您使用的语言不支持某些功能,使用它比对抗它或尝试从其他语言导入您最喜欢的功能更容易。 (“如果你不能使用你喜欢的编程语言,那就去爱你所使用的语言”)。
话又说回来,也许我这有点傲慢。 多年来,整个面向方面编程运动一直在向 Java 注入新的功能(但我可能会补充说,除了 JBoss 之外,从未获得太多关注)。 不管怎样,弗拉基米尔因为在他的例子中使用忍者神龟而获得了额外的荣誉。
另一方面:作为一个相对的 Objective-C 菜鸟,在我看来,类别在我在网络上找到的示例代码中被过度使用了。 将静态帮助器方法添加到具有类别的系统类中似乎是常见的做法,因为创建一个帮助器类来在项目中容纳这些方法同样容易,并且在更新系统类或导入时破坏它们的风险较小别人的图书馆有自己的此类类别。 一个常见的示例是向 UIColor 添加新的静态颜色方法。 为什么不将它们添加到本地类中呢?
我见过的类别的一个真正好的用途是添加方法,不是向系统类,而是向生成的类添加方法。 因此,当您从核心数据对象模型生成类时,并且您想要添加新的构造函数或其他真正属于模型类的方法时,您可以使用类别来实现,从而使您能够安全地如果您更改模型,请重新生成模型类,而不会丢失您的工作。
总之:
- 忘记类别作为混入的解决方案
- 类别对于核心数据很有用,但在其他方面却被过度使用和高估
To be clear the answer is NO - they are not the same.
The differences are outlined by John Calsbeek in the accepted answer, but I would say the key difference is the one where mixins can be used in different classes, whereas categories always extend exactly one class - which they declare in their definition.
This is the key difference because it means the use cases for these two features are utterly different. Another way of looking at it is that, if you're coming from Ruby to Objective-C and missing your mixins, you won't find any joy with categories.
The use case for mixins is that you have some code - methods and instance variables - that you want to reuse in several classes that don't have a common superclass. You can't do that with categories.
Mixins are effectively "multiple-inheritance" of the type you don't find in Objective-C. The closest thing in objective-c is protocols, just as the closest thing Java is interfaces, but they have neither instance variables nor method bodies (in objective-C or java). So you're generally left with creating helper classes or putting code in superclasses.
The use case for objective-c categories is that you want to add methods to an existing class - even a system or library class.
I would say that mixins are more powerful, but since it's an apples-to-oranges comparison, it would be pointless.
To be accurate:
the Ruby equivalent of Categories, is to simply reopen the class you want to extend and extend it. (You can do that anywhere in Ruby, and it's effectively identical to Categories)
I'm not sure what the objective-c equivalent to Mixins is though - anyone?
[Update] A bit more searching, and no there isn't an equivalent of Mixins in Objective-C, but the enterprising Vladimir Mitrovic has created a library that effectively does it. https://github.com/vl4dimir/ObjectiveMixin
I'm in two minds as to whether to use it or not: sometimes if the language you're using doesn't support something, it's easier to work with it rather than fight it or try to import your favourite features from other languages. ("If you can't be with the programming language you love, love the one you're with").
Then again, perhaps that's just a bit to snooty of me. The whole Aspect Oriented Programming movement has been glomming features onto Java for years (but never gaining much traction, I might add, outside of JBoss). Anyway, Vladimir gets extra kudos for using Ninja Turtles in his example.
On another side node: as a relative objective-c noob, it seems to me that categories are way overused in sample code I find all over the web. It seems common practice to add static helper methods to system classes with categories, when it would be just as easy to create a helper class to house those methods in your project, with less risk of them breaking when the system class is updated or you import someone else's library with their own such categories. A common example is adding new static color methods to UIColor. Why not just add them to a local class?
The one really good use I've seen for categories is adding methods, not to system classes, but to generated classes. So when you generate classes from your core-data object model, and you want to add new constructors or other methods that really do belong in the model class, you can do it with categories, allowing you to safely regenerate the model class if you change your model, without losing your work.
In summary:
- forget about categories as a solution for mixins
- categories are good for core-data but overused and overrated otherwise
类别是为特定类定义的,据我所知,您不能创建一个类别并将其实现的方法添加到多个类中。
Categories are defined for a particular class, as far as I know, you can't create a category and add the methods it implements to several classes.
使用 mixin,您可以从基类和 mixin 派生一个新类,然后实例化这个新类以利用它。
使用类别,您可以有效地直接添加基类,以便该基类的所有实例都可以访问该类别提供的功能。
With a mixin, you might derive a new class from your base and the mixin, then instantiate this new class to take advantage of it.
With a category, you are effectively adding directly the base class, so that all instances of that base have access to the functionality provided by the category.