Hi,
Can a Objective c interface have more than one implementation? Example I could have a interface but 2 implementations one where i use an arrays or another where I use a stack..etc to implement it.
If so how do you call it / syntax?
Thanks
Hi,
Can a Objective c interface have more than one implementation? Example I could have a interface but 2 implementations one where i use an arrays or another where I use a stack..etc to implement it.
If so how do you call it / syntax?
Thanks
You mean for example like this:
@interface MasterViewController :
UIViewController <GKPeerPickerControllerDelegate,
GKSessionDelegate,
UITextFieldDelegate,
UITableViewDelegate,
AVAudioRecorderDelegate> {
}
Objective-C has the concept of a Protocol, which is the specification of an interface. Through Protocols, Objective-C fully supports multiple inheritance of specification (but not implementation). So, a bit confusingly, the @interface syntax actually defines the class (implementation), which only supports single inheritance, but can specify the implementation of many / multiple inheritance of Protocols, or specifications of interfaces. In the end, this is very similar in nature to Java.
For example:
@protocol SomeInterface
- (void)interfaceMethod1;
- (void)interfaceMethod2;
@end
@interface SomeClass:NSObject <SomeInterface>
@end
@interface AnotherClass:NSObject <SomeInterface>
@end
Instances of either SomeClass
or AnotherClass
both claim that they provide the implementation required for the SomeInterface
protocol.
Objective-C is dynamically typed and doesn't require that the object actually specify the message being sent to it. In other words, you can indiscriminately call any method you would like on SomeClass
, whether it is specified in it's interface or any of its protocols or not (not that this would necessarily be a productive or positive thing to do).
Therefore, all of the following would compile (although with warnings) and run fine, although the messages / methods without implementation is basically a no op in this case. Objective-C has a fairly complicated (and very cool) process of handling method calling / forwarding that is a bit beyond the scope of this question.
SomeClass * someObject = [[SomeClass alloc] init;
[someObject someUnspecifiedMethod]; // Compiles with warning - no op
[someObject interfaceMethod1];
If you wish to define something that can be any class (@interface) type but implements a specific interface (@protocol), you can use something like this:
id <SomeInterface> obj;
obj
could hold either a SomeClass
or AnotherClass
object.
Perhaps you should try Cocoa pattern called Class Cluster. To start using it you need to create public class called SomeClass
and two private subclasses SomeArrayClass
and SomeStackClass
. When you need to use stack your public class constructor will create instance of SomeStackClass
and will return it as publicly available instance of SomeClass
.
(If you give this a vote, please give Roman a vote -- his answer was first, is correct, just lacked an example).
You are talking about a Class Cluster. For an example, look at the NSString class.
There is NSString:
@interface NSString : NSObject
And NSMutableString:
@interface NSMutableString : NSString
Both of which declare an extremely small set of methods in the core class's declaration. If you were to subclass NSString to implement your own string class, you would only need to implement those core methods. All other methods implemented in NSString are implemented in terms of those core methods. And, likewise, the mutation methods are implemented using the primitive methods declared in the core of NSMutableString.
Now, obviously, implementing all mutability via - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString
(the one core method) would be grossly inefficient. Thus, at runtime, you'll note that you never actually have an instance of NSString or NSMutableString, but only instances of subclasses (which, actually, aren't really subclasses... but they might as well be in the context of this discussion).
And those subclasses -- the implementation class used at runtime -- overrides almost all of the methods of NSString and NSMutableString to provide highly optimized implementations of the specific operations.
So, you would do something like:
@interface MyAbstractClass : NSObject
... declare factory methods here ...
... declare core methods here ...
@end
@interface MyAbstractClass(AdditionalFunctionality)
... declare convenience here ...
@end
Then, in the implementation, implement all of the core methods as @throw @"Must use subclass"
and all AdditionalFunctionality
methods in terms of the core methods.
This could be entirely private -- not in a header at all, even:
@interface MyStackClass : MyAbstractClass @end
@implementation MyStackClass ... implement the core methods and override the additionalfunctionality methods that need optimization ... @end
Repeat for your additional types of classes. Then, implement factory methods on MyAbstractClass that return instances of the subclasses, as needed.