1

I'm coming to Objective-C from ECMAScript like languages, so this is probably the wrong question, but I can't determine how else to ask it:

I have an interface defined in a header file. I don't want to implement it directly, I just want classes to use it.

So say: Car.h is implemented by Telsa.m, Mercedes.m, Peugeot.m, etc.

Is this possible? I have no use for a default implementation of "car", but I want to make sure each of the brands implements the interface so I can pass any "Car" around reliably. I don't want it to be possible to instance a Car.

Thanks in advance for any insight.

3 Answers 3

5

What you are looking for is a protocol, defined in Objective-C using @protocol. These are, perhaps confusingly, the equivalent of Java-style interfaces. You can define a class to implement any number of protocols, and there is no default implementation required. Read Apple's Working with Protocols for the details.

HTH

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick answer. I awarded it to the answer with example code, but I appreciate the speed. I was able to do what I wanted with a Protocol. Thanks so much! :)
2

In objective-c when you want to write a class you have to specify the class interface (@interface usually in .h file) and the class implmentation (.m file)

When you want to define an interface that any other class can implement in objective-c thats called a protocol.

@protocol XYZPieChartViewDataSource
- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
@optional
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;
- (BOOL)shouldExplodeSegmentAtIndex:(NSUInteger)segmentIndex;
@required
- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;
@end

Therefore you can write a class that implements this protocol, in order to do this first you have to declare that your class implements this protocol (.h file).

@interface MyClass : NSObject <XYZPieChartViewDataSource>
...
@end

After that you have to write the methods that you want to implement, you must write the required ones and you can write if you need to the optional ones

- (BOOL)shouldExplodeSegmentAtIndex:(NSUInteger)segmentIndex {
// do someting
}

- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex {
// do someting 
}

As they pointed out you can take a look to the protocol docs: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html

1 Comment

Giving it to you since you put the relevant code in here as well.
0

To use a protocol for that is a good pattern, because it is very flexible. But looking to your classes Tesla … it seems to be that way, that these are subclasses of a base class Car.

In such cases it might be more convenient for the implementation to make Car a partial abstract base class. That means that Car

  • declares the API as you want
  • partially implements the API
  • is never instantiated

The advantage is that you have to implement methods equal in every subclass in the base class. So it shortens the implementation.

Of course, you can combine that:

@interface Car : NSObject <CarProtocol>
…
@end

@implementation Car
// Define methods that are common for all subclasses of Car
// Define methods included in CarProtocol, but not definable in a base class empty. 
…
@end

@interface Tesla : Car // Protocol is inherited
…
@end

@implementation Tesla
// Override methods that needs a special behavior for this subclass
// Override methods that are not definable at the base class
// Add method definitions that are special to Tesla (i. e. Power plug)
…
@end

@interface AmphibiousCraft : NSObject<CarProtocol, ShipProtocol> // Implementation of Car is no real help
…
@end

@implementation AmphibiousCraft
…
@end

2 Comments

From what I've been reading, since Objective-C doesn't formally support abstract classes, that Protocols make more sense in this scenario?
As mentioned you can combine that: To define the public API, use formal protocols (@protocol). To implement them use abstract base classes to reduce code repetitions. Otherwise you will finde yourself writing the same code again and again in Tesla, Mercedes, Peugeot and so on.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.