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?
To the best of my understanding:
Mixins
Syntactic sugar for composition
Added by the developer of the class, not the user
Can be reused by multiple classes
Can add instance variables
Can be implemented using forwarding in Objective-C
Categories
Similar to extension methods in other languages
Usually added by the user of the class, not the developer
Used by exactly one class and its subclasses
Can't add instance variables
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.
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.
Related
Objective-C’s objects are pretty flexible when compared to similar languages like C++ and can be extended at runtime via Categories or through runtime functions.
Any idea what this sentence means? I am relatively new to Objective-C
While technically true, it may be confusing to the reader to call category extension "at runtime." As Justin Meiners explains, categories allow you to add additional methods to an existing class without requiring access to the existing class's source code. The use of categories is fairly common in Objective-C, though there are some dangers. If two different categories add the same method to the same class, then the behavior is undefined. Since you cannot know whether some other part of the system (perhaps even a system library) adds a category method, you typically must add a prefix to prevent collisions (for example rather than swappedString, a better name would likely be something like rnc_swappedString if this were part of RNCryptor for instance.)
As I said, it is technically true that categories are added at runtime, but from the programmer's point of view, categories are written as though just part of the class, so most people think of them as being a compile-time choice. It is very rare to decide at runtime whether to add a category method or not.
As a beginner, you should be aware of categories, but slow to create new ones. Creating categories is a somewhat intermediate-level skill. It's not something to avoid, but not something you'll use every day. It's very easy to overuse them. See Justin's link for more information.
On the other hand, "runtime functions" really do add new functionality to existing classes or even specific objects at runtime, and are completely under the control of code. You can, at runtime, modify a class such that it responds to a method it didn't previously respond to. You can even generate entirely new classes at runtime that did not exist when the program was compiled, and you can change the class of existing objects. (This is exactly how Key-Value Observation is implemented.)
Modifying classes and objects using the runtime is an advanced skill. You should not even consider using these techniques in production code until you have significant experience. And when you have that experience, it will tell you that you very seldom what to do this anyway. You will know the runtime functions because they are C-based, with names like method_exchangeImplmentations. You won't mistake them for normal ObjC (and you generally have to import objc/runtime.h to get to them.)
There is a middle-ground that bleeds into runtime manipulation called message forwarding and dynamic message resolution. This is often used for proxy objects, and is implemented with -forwardingTargetForSelector, +resolveInstanceMethod, and some similar methods. These are tools that allow classes to modify themselves at runtime, and is much less dangerous than modifying other classes (i.e. "swizzling").
It's also important to consider how all of this translates to Swift. In general, Swift has discouraged and restricted the use of runtime class manipulation, but it embraces (and improves) category-like extensions. By the time you're experienced enough to dig into the runtime, you will likely find it an even more obscure skill than it is today. But you will use extensions (Swift's version of categories) in every program.
A category allows you to add functionality to an existing class that you do not have access to source code for (System frameworks, 3rd party APIs etc). This functionality is possible by adding methods to a class at runtime.
For example lets say I wanted to add a method to NSString that swapped uppercase and lowercase letters called -swappedString. In static languages (such as C++), extending classes like this is more difficult. I would have to create a subclass of NSString (or a helper function). While my own code could take advantage of my subclass, any instance created in a library would not use my subclass and would not have my method.
Using categories I can extend any class, such as adding a -swappedString method and use it on any instance of the class, such asNSString transparently [anyString swappedString];.
You can learn more details from Apple's Docs
One drawback to using composition in place of inheritance is that all of the methods being provided by the composed classes must be implemented in the derived class, even if they are only forwarding methods.
Looking for the solution to this problem I came cross something called as Traits and mixin ( available in language like scala,Perl 6) . However I haven't been compleltly able to understand the idea behind traits and mixins.
My question is how does traits (or Mixins) solve the problem of delegation with composition ?
I'm not a Perl or Scala programmer, but no one else has tried to answer your question, so I will attempt it. Traits or mixins are an alternative to multiple inheritance. C++ implemented multiple inheritance, but there were some problems with it. Successive languages like Java and C# decided to implement only single inheritance. But single inheritance can be inconvenient, just as you say; if you want to use methods from multiple classes, you must compose instances of those classes and then write methods to forward messages to the composed objects.
Traits/mixins are a solution to inconvenience of single inheritance. Instead of composing objects and writing forwarding methods yourself, the programming language does the work for you. If your object does not understand some message sent to it, the runtime environment will look through all of the traits/mixin to see if one of them understands the message. If a trait/mixin understands the message, then that trait's implementation of the is executed. This lets you bundle commonly used functionality into a single component, called a trait or mixin, so you use it in many places.
I think the important advantage of traits/mixins over multiple inheritance is that when different mixins implement methods with the same name, you can predict which method will be executed. Knowing which method would be executed in C++ was a problem. See the Wikipedia article on the "diamond problem" (http://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem)
How can I share code between classes in Objective-C, the way Traits in PHP work?
I thought of using categories, but I wondered if there is something more suitable when it wouldn't be sensible to use inheritance.
There are several ways to share code between classes and each one has its own importance, depending upon the situation:
You can use inheritance.
You can declare Global Methods.
You can put the sharable code in AppDelegate.
You can use Singleton Class and put the common code in that class. (Not preferred for sharing code but we can still do it.)
All methods have their own pros/cons. You need to study their applications and use. Hope it helps.
Depends. You should ask yourself why do you want to have the same behaviour in various classes. You can use: Inheritance or design patterns (e.g. Composite pattern).
See:
Does Objective-C support traits/mixins?
Not sure if this is the best practice, or what you mean by "sharing code" but I usually have a static class which can hold global values.
The class is static and you can access it from anywhere like this:
[dataModel getMyValue];
[dataModel setMyValue];
It only becomes an issues if you try to write to it from multiple threads, but other than that its a good way to store shared data in your app.
Sharing code in Objective-C can be done only via subclassing or doing composition.
There is no equivalent of PHP's traits here. Categories work in a little bit different way. They're are assigned to a certain class, so you can't use code from category in any class. Unless you create NSObject category, which is good idea only in rare cases. You can treat category as a class extension.
It's possible 'share' interfaces having many different protocols. But it's not exactly what you need, I guess.
I'm trying to understand whether the answer to the following question is the same in all major OOP languages; and if not, then how do those languages differ.
Suppose I have class A that defines methods act and jump; method act calls method jump. A's subclass B overrides method jump (i.e., the appropriate syntax is used to ensure that whenever jump is called, the implementation in class B is used).
I have object b of class B. I want it to behave exactly as if it was of class A. In other words, I want the jump to be performed using the implementation in A. What are my options in different languages?
For example, can I achieve this with some form of downcasting? Or perhaps by creating a proxy object that knows which methods to call?
I would want to avoid creating a brand new object of class A and carefully setting up the sharing of internal state between a and b because that's obviously not future-proof, and complicated. I would also want to avoid copying the state of b into a brand new object of class A because there might be a lot of data to copy.
UPDATE
I asked this question specifically about Python, but it seems this is impossible to achieve in Python and technically it can be done... kinda..
It appears that apart from technical feasibility, there's a strong argument against doing this from a design perspective. I'm asking about that in a separate question.
The comments reiterated: Prefer composition over inheritance.
Inheritance works well when your subclasses have well defined behavioural differences from their superclass, but you'll frequently hit a point where that model gets awkward or stops making sense. At that point, you need to reconsider your design.
Composition is usually the better solution. Delegating your object's varying behaviour to a different object (or objects) may reduce or eliminate your need for subclassing.
In your case, the behavioural differences between class A and class B could be encapsulated in the Strategy pattern. You could then change the behaviour of class A (and class B, if still required) at the instance level, simply by assigning a new strategy.
The Strategy pattern may require more code in the short run, but it's clean and maintainable. Method swizzling, monkey patching, and all those cool things that allow us to poke around in our specific language implementation are fun, but the potential for unexpected side effects is high and the code tends to be difficult to maintain.
What you are asking is completely unrelated/unsupported by OOP programming.
If you subclass an object A with class B and override its methods, when a concrete instance of B is created then all the overriden/new implementation of the base methods are associated with it (either we talk about Java or C++ with virtual tables etc).
You have instantiated object B.
Why would you expect that you could/would/should be able to call the method of the superclass if you have overriden that method?
You could call it explicitely of course e.g. by calling super inside the method, but you can not do it automatically, and casting will not help you do that either.
I can't imagine why you would want to do that.
If you need to use class A then use class A.
If you need to override its functionality then use its subclass B.
Most programming languages go to some trouble to support dynamic dispatch of virtual functions (the case of calling the overridden method jump in a subclass instead of the parent class's implementation) -- to the degree that working around it or avoiding it is difficult. In general, specialization/polymorphism is a desirable feature -- arguably a goal of OOP in the first place.
Take a look at the Wikipedia article on Virtual Functions, which gives a useful overview of the support for virtual functions in many programming languages. It will give you a place to start when considering a specific language, as well as the trade-offs to weigh when looking at a language where the programmer can control how dispatch behaves (see the section on C++, for example).
So loosely, the answer to your question is, "No, the behavior is not the same in all programming languages." Furthermore, there is no language independent solution. C++ may be your best bet if you need the behavior.
You can actually do this with Python (sort of), with some awful hacks. It requires that you implement something like the wrappers we were discussing in your first Python-specific question, but as a subclass of B. You then need to implement write-proxying as well (the wrapper object shouldn't contain any of the state normally associated with the class hierarchy, it should redirect all attribute access to the underlying instance of B.
But rather than redirecting method lookup to A and then calling the method with the wrapped instance, you'd call the method passing the wrapper object as self. This is legal because the wrapper class is a subclass of B, so the wrapper instance is an instance of the classes whose methods you're calling.
This would be very strange code, requiring you to dynamically generate classes using both IS-A and HAS-A relationships at the same time. It would probably also end up fairly fragile and have bizarre results in a lot of corner cases (you generally can't write 100% perfect wrapper classes in Python exactly because this sort of strange thing is possible).
I'm completely leaving aside weather this is a good idea or not.
I've recently discovered categories and was wondering when it might be appropriate to use them in a user defined class/new class. For example, I can see the benefits of adding a category to an existing class like NSString, but when creating a new class what would be the advantage of adding a category to this rather than just implementing a normal method?
Hope this makes sense.
Many thanks
Jules
The answer isn't really any different for your own classes than it is for framework classes. If you have multiple projects, you'll likely end up sharing some classes between them. However, you may want to extend some of your classes so that they work more easily with a specific project, but not want to include those extra methods in your other projects, where they might not make sense. You can use a category to extend your class without needing to subclass.
If I understand your question correctly, creating a "new class" is always "subclassing" because you're subclassing NSObject at the very least.
You could use categories on a new class to separate out sections of responsibility of a complex class. For example, all the basic functionality (instance variables, accessors, description, etc.) can go in one file (the "main" class file) while all methods to support a protocol (such as NSTableViewDataSource) can go in another.
Some take this approach to keep things "neat". I'm a firm believer in "if it's my own custom class, all its code should be in one file" so I do not personally do this. I demarcate different logical aspects of the class' code with "#pragma mark Some Section Name" to help navigation and readability. Your mileage may vary.
Adding a Category on NSString is useful when you want to call a method on every single NSString instance you will encounter. This is a real improvement over inheritance for this kind of object because they are used by the core framework and you don't have to convert a NSString object to your subclass when you want to call your custom method.
On the other hand, you can just put methods in, no instance variables.
In the book Refactoring by Martin Fowler, he has a section titled "Introduce Foreign Method" (A server class you are using needs an additional method, but you can't modify the class.) That's what categories are good for.
That said, there are times when using a category, instead of changing the class, is appropriate. A good example on using a category, even though you could change the server class, is how Apple handled the UIViewController MediaPlayer Additions. They could have put these two methods in UIViewController itself but since the only people who would ever use them are people who are using the Media Player framework, it made more sense to keep the methods there.