Multiple inheritance is a technique, used in C++ and some other object-oriented languages, whereby an object can inherit data and behavior from multiple superclasses. For the sake of simplicity, Objective C does not include multiple inheritance directly. Most of the time, using protocols or categories instead is a better solution. However, thanks to dynamic typing, you can also provide much of the function of multiple inheritance using OpenStep's implementation of NSObject. Here's how:
+ Create the classes from which you want your subclass to inherit. Be sure that your classes preserve encapsulation: you will not have direct access to your superclass' public instance variables.
+ Create a new subclass of NSObject and give it one instance variable: an array of objects of type id.
+ Create an init method that initializes one instance of each object from which you want your new object to 'inherit' and adds it to the array.
+ Override the forwardInvocation: method in your subclass. Your new method needs to do the following:
- Step through the array, testing each element with respondsToSelector: and the selector specified by the invocation. - If any array element responds to the selector, invoke the message on that element.
- If no element responds to the selector, call [self doesNotRecognizeSelector].
+ If you need to, override your subclass' respondsToSelector: method. This will not be necessary in most cases. The default implementation of respondsToSelector: does not recognize forwarding; that is, your new object will return NO to [myMIObject respondsToSelector:foo] even if it is able to forward foo messages to one of the elements of its array. Your new respondsToSelector method should:
- Step through the array, testing each element with respondsToSelector: and the selector specified.
- If any array element responds to the selector, return YES.
- If no array element responds to the selector, manually test the selector against each of your class' class and instance methods, if any.
- If your class does not respond to the selector, return [super respondsToSelector] to check the methods inherited from NSObject.
Since forwardInvocation: is only called if your new object can't respond to a message, you can override classes from either 'superclass' just as you would if they were true superclasses.
This particular implementation allows you to change the 'inheritance' of your object at runtime by changing the array; you could of course design a class along similar lines using statically typed instance variables instead of an array. This would allow you to design superclass objects that could communicate directly with each other through delegation or notification.
For more information on the techniques used here, see the Foundation framework documentation on the NSObject class, the NSObject protocol (for respondsToSelector:), and the NSInvocation class.