views:

441

answers:

4

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

+1  A: 

You mean for example like this:

@interface MasterViewController : 
  UIViewController <GKPeerPickerControllerDelegate, 
                    GKSessionDelegate,
                    UITextFieldDelegate,
                    UITableViewDelegate,
                    AVAudioRecorderDelegate> {
}
Tuomas Pelkonen
Or do you actually mean more that one @implementation/@end block?
Tuomas Pelkonen
+7  A: 

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.

rcw3
There is an easier way.
bbum
You're right... I answered a much more "base" question (and not really the one the OP was asking)... after re-reading, I can see the OP was probably looking for something more in line with your answer / abstract factories / class clusters.
rcw3
+17  A: 

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.

Roman Busyghin
This is exactly the pattern you want to use.
bbum
How about using "Protocols" ? It's closer to java/c# interfaces.which is what I want.
+15  A: 

(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.

bbum