"Protocols" are, along with
categories (see my writeup under
Category), how
Objective C handles
mix-ins and how it gets around the fact it does
not have
multiple inheritance. Protocols and categories encompass one of the more visible bits of Objective C's
Smalltalk heritage, and are taken together really rather similar to a more nimble (in my opinion, anyway) equivalent of the
interface )("
implements") capability in
java. Protocols greatly simplify certain odd issues of class structure and
polymorphism that are very clumsy to deal with.
Basically all a protocol does is group classes by functionality; a protocol prototypes a certain number of methods, and if a class adopts a protocol it is agreeing to implement every single one of the methods specified in the protocol. The class can then be described by the type of the protocol, and in general can be treated as if the protocol was a class it had inherited from.
If we were going to create a protocol named DemoProtocol, the syntax would look like this:
In DemoProtocol.h:
@protocol DemoProtocol
- thing1;
- thing2;
@end
If
class HypotheticalClass wanted to adopt DemoProtocol, all it would have to do is add it to the end of its
@implementation line surrounded by <html brackets>, for example changing
@implementation HypotheticalClass to
@implementation HypotheticalClass <DemoProtocol>.
Categories can adopt protocols, and
protocols can adopt other protocols, in the same way. Any of these can adopt multiple protocols, by listing multiple protocols between the <> brackets separated by commas. If a class has adopted DemoProtocol by any of these means, it *must* implement methods named thing1 and thing2. Any class that has adopted DemoProtocol, however, can be passed in methods and functions as (DemoProtocol *), and the
type checking system will be fine with that.
Protocols let you abstractly describe a functionality that could be implemented by a variety of classes in different ways; for example, NeXTStep has a protocol for event handlers. Without protocols, either all event handlers would have to be subclasses of NSEventHandler, which would be unrealistic and restrictive, or the event handling functions of NeXTStep would have to simply assume any id passed to it supports the event handling methods, without the benefit of compile-time type checking etc.
The @protocol @-directive can be used in three ways: to declare a protocol, as outlined above; to alert the compiler to the existence of a protocol defined in another file, the same way the @class directive works (see my writeup under @); and to return a protocol object (Every protocol has a corresponding instance variable of class Protocol; you can say @protocol( DemoProtocol ) somewhere in your code, and it will return a pointer to the protocol instance variable corresponding to DemoProtocol. There are defined in NSObject both class method and instance methods named conformsToProtocol(Protocol *)aProtocol; you send this message to any object, and it returns a BOOL stating whether the object adopts aProtocol, which you find the value of by using the @protocol() directive.
The language-imposed protocols i have just described are often called "Formal Protocols"; there is also something called an Informal Protocol (see the node).