Oddly enough, I was just thinking about interfaces (aka protocols) after driving home from watching some high school students learning about C++.
This won’t be terribly well-organized, so bear with me.
You obviously understand the basics, so this piece of what I was thinking about isn’t terribly important, but it struck me that one way to describe interfaces to new programmers is to think about conceptual interfaces in real life. Not keyboards and mice, but ATMs, debit cards, and tellers for banks. Many banks treat human tellers as deprecated interfaces, but few have the courage to do away with them entirely. ATMs are great, debit cards are better, because there’s no paper, just digital cash.
The important point to those interfaces is that their standardization makes life easier for people. Switch banks? No problem. You’re still using ATMs, tellers, and debit cards.
Objective-C has the advantage over C++ in that you can send any message to any object, at least as far as the compiler is concerned. C++ demands that an object conform to a specific interface (via inheritance, typically) before you’re allowed to call methods related to that interface.
But still, protocols/interfaces give us a comfort level, a standardization that we can take advantage of. An interface specification is an agreement that you can test against, for example, so if you have a thorough set of tests, you can replace one library that conforms to that interface with a different one entirely and see if your tests still pass. If so, you’re probably good to go.
The biggest reason I like interfaces is that I utterly despise inheritance. It’s a necessary evil, but it’s rarely really necessary. It’s the lazy man’s approach to OO. (Ok, so that might be an overstatement, and I might actually have a pathology in this regard.)
To give you an example from tonight, the class I was attending is an after-school robotics project, and the instructor described their use of inheritance for sensors: accelerometers and gyroscopes are both subclasses of the sensor class. I asked whether they both implemented the same methods (messages) or actually shared any code, and it turned out the only code they shared was an interface with a processing board. So rather than inheritance, they could have defined a sensor interface, and both types could have used an interface object as a member. No inheritance needed.
I’d really like to explore Eiffel someday; all I know about it is that it takes interfaces to a new level, by declaring explicit agreements between classes. See en.wikipedia.org/wiki/Design_by_contract
Small programs don’t need interfaces, but any project of significant size, especially that requires multiple programmers, should seriously consider them.