This is a question of class design with Objective-C. Here is an example:
File systems have files and directories. Both are "nodes". Walking a directory for example yields a list of nodes, some being [sub]directories, other being files.
This points to the following client-side abstract view of the class hierarchy:
@interface Node: NSObject {}
@end
@interface Directory: Node {}
@end
@interface File: Node {}
@end
So far so good. At this point, all three classes are abstract. Now going to implementation, you realize there are two main routes: using URLs (recommended by Apple for Mac OS X ≥ 10.6), or paths (only possible way for Mac OS X ≤ 10.5 or Cocotron).
So now, you need to develop two concrete implementations of each of the three abstract classes above:
// Node subclasses
@class NodeWithPath;
@class NodeWithURL;
// Directory subclasses
@class DirectoryWithPath;
@class DirectoryWithURL;
// File subclasses
@class FileWithPath;
@class FileWithURL;
Now consider, say, FileWithURL
:
- it is a file, so it should inherit from
File
. - it is a node implemented with an URL, so it should inherit from
NodeWithURL
But File
and NodeWithURL
are not within the same class hierarchy line. Without multiple inheritance, there is no way to express that in Objective-C.
So how would you design this situation? I can see two ideas:
- use protocols, which are a limited form of multiple inheritance.
- use members (has-a instead of is-a relationships).
I tend to favor the protocol idea. In that case, Directory
and File
would be protocols, and the six concrete classes would inherit from a common Node
superclass and conform to their counterpart protocol. Node
would have two subclass hierarchies: one using URLs, one using Paths.
Now there is the issue of hiding the implementation from the client code. A class cluster can be setup for this purpose with the Node
common superclass. Client code would get objects typed as Node<File>
or Node<Directory>
as the case may be.
Any additional/other/similar/different ideas?