Categories are not really the right choice here, if I understand the question properly. The right feature is a protocol.
Let me give an example. Suppose you want a bunch of your classes to have a specific ability called "sing". Then you define a protocol:
@protocol Singer
- (void) sing;
@end
Now you can declare that any of your own classes adopts the protocol the following way:
@interface Rectangle : Shape <Singer> {
<snip>
@end
@interface Car : Vehicle <Singer> {
<snip>
@end
Be declaring that they adopt the protocol they commit themselves to implement the sing
method. For example:
@implementation Rectangle
- (void) sing {
[self flashInBrightColors];
}
@end
@implementation Car
- (void) sing {
[self honk];
}
@end
Then you use those classes for example like this:
void choral(NSArray *choir) // the choir holds any kind of singer
{
id<Singer> aSinger;
for (aSinger in choir) {
[aSinger sing];
}
}
Notice that the singers in the array don't need to have a common superclass. Notice also that a class can have only one superclass, but many adopted protocols. Notice finally that type checking is done by the compiler.
In effect, the protocol mechanism is multiple inheritance used for the mixin pattern. That multiple inheritance is severely limited because a protocol cannot add new instance variables to a class. A protocol only describes a public interface adopters must implement. Unlike Ruby modules it does not contain an implementation.
That's the most of it. Let's mention categories however.
A category is declared not in angle brackets, but between parenthesis. The difference is that a category can be defined for an existing class to expand it without subclassing it. You can even do so for a system class. As you can imagine, it's possible to use categories to implement something similar to mixin. And they were used that way for a long time usually as category to NSObject
(the typical root of the inheritance hierarchy), to such an extent that they were called "informal" protocols.
It's informal because 1- no type checking is done by the compiler, and 2- implementing the protocol methods is optional.
There is no need today to use categories as protocols, especially because the formal protocols can now declare that some of their methods are optional with the keyword @optional
or required (the default) with @required
.
Categories are still useful to add some domain specific behavior to an existing class. NSString
is a common target for that.
It's also interesting to point out that most (if not all) of NSObject
facilities are in fact declared in a NSObject
protocol. This means that it's not really compelling to use NSObject
as a common superclass for all classes, though this is still commonly done for historical reasons, and well... because there is no drawback for doing so. But some system classes, such as NSProxy
, are not NSObject
.