2) To declare the interface to an object while concealing its class
@protocol DatabaseConnection
- (QueryResult*) runQuery:(NSString*)query;
- (void) close;
@end
@interface MySQLConnection : NSObject <DatabaseConnection> {
...
}
@interface OracleConnection : NSObject <DatabaseConnection> {
...
}
// imagine a method on some class that will give you a connection
- (DatabaseConnection*) getConnection {
// some logic to determine which connection to return
if (something)
return [[[OracleConnection alloc] init] autorelease];
else
return [[[MySQLConnection alloc] init] autorelease];
}
and you using it like so in client code ...
id <DatabaseConnection> con = [SomeClass getConnection];
QueryResult* result = [con runQuery:@"select * from users"];
[con close];
Notice how we are abstracted away from the actual database implementation and can run our query regardless of which database we're talking with.
The advantage of defining DatabaseConnection
as a protocol as opposed to a base class is that we don't have to provide a default implementation. Because in this case, the default implementation would not make sense. A protocol is Objective-C's way of doing a purely abstract base class in C++ or an interface in Java.
3) To capture similarities among classes that are not hierarchically related.
You might want the ability to ask any object about which class it implements.
- (Class)class;
You might also want to know what its superclass is.
- (Class)superclass;
Perhaps you want to ask if any two objects are equal.
- (BOOL)isEqual:(id)object;
All of these things and more are methods you may want on classes such as File, MySQLConnection, User, MonsterX, MiniGun. Though these classes are entirely different from an inheritance point of view, which is why they can't share a base class, a protocol addresses this need.
For example, Objective-C has a base protocol called NSObject.
Note: There will be some who point out that most Objective-C classes inherit from the NSObject class and that they get a number of these methods from there.
This statement is true. But NSObject
the class, implements NSObject
the protocol. Apple recognized that there will be cases when your objects do not inherit from NSObject
the class, but may still want to provide services such as responding to the description
method.