Polymorphism has saved my buns quite a few times on various projects. When using languages that support interfaces, like Java or Delphi, I tend to design around them. This allows me to focus on functionality rather than classes.
In other words, when interfaces are passed around and used, rather than classes, I ultimately don’t care what the class is “hiding behind” the interface. The only question is whether that class provides the functionality the interface “contract” specifies. New functionality can be obtained seamlessly by hiding a new class behind the required interface. Similar comments can be made about the strong information hiding aspect of interfaces.
Objective C protocols are similar in many respects to interfaces. The one big syntactic difference that bit me was that you can’t declare a variable’s type to be a protocol. In the following example, I can’t declare myLocalVariable to be any kind of protocol (something I would do in other languages).
@protocol SomeProtocol - (void) foo; ... @end . . . SomeProtocol myLocalVariable; //SomeProtocol *myLocalVariable; <-- this is also wrong … [myLocalVariable foo];
Having found interfaces a key language feature when designing, this caused some heartburn at first. Objective C, however, allows one to include a protocol in type declarations. Thus, the code becomes:
myLocalVariable; … [myLocalVariable foo];
With this syntax, I can continue to focus on designing around functionality rather than classes.
But Wait! There's More!
If id <SomeProtocol> has your gears turning, you can apply the syntax one step further. This may only be useful in specific situations, but here it is for the record.
You need not stop at the generic id, and may use any class. For example, given a parent class ParentClass, you could ensure that a variable accepts any descendant of ParentClass that also supports the SomeProtocol protocol thus:
*myLocalVariable; … [myLocalVariable foo];
Note that you must still pay attention to the usual caveat that id is an implied pointer declaration, and must not include the star (*) after it like all other classes do. id is still the equivalent of (void *).