Creating an abstract class in Objective-C Creating an abstract class in Objective-C objective-c objective-c

Creating an abstract class in Objective-C


Typically, Objective-C class are abstract by convention only—if the author documents a class as abstract, just don't use it without subclassing it. There is no compile-time enforcement that prevents instantiation of an abstract class, however. In fact, there is nothing to stop a user from providing implementations of abstract methods via a category (i.e. at runtime). You can force a user to at least override certain methods by raising an exception in those methods implementation in your abstract class:

[NSException raise:NSInternalInconsistencyException             format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)];

If your method returns a value, it's a bit easier to use

@throw [NSException exceptionWithName:NSInternalInconsistencyException                               reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]                             userInfo:nil];

as then you don't need to add a return statement from the method.

If the abstract class is really an interface (i.e. has no concrete method implementations), using an Objective-C protocol is the more appropriate option.


No, there is no way to create an abstract class in Objective-C.

You can mock an abstract class - by making the methods/ selectors call doesNotRecognizeSelector: and therefore raise an exception making the class unusable.

For example:

- (id)someMethod:(SomeObject*)blah{     [self doesNotRecognizeSelector:_cmd];     return nil;}

You can also do this for init.


Just riffing on @Barry Wark's answer above (and updating for iOS 4.3) and leaving this for my own reference:

#define mustOverride() @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"%s must be overridden in a subclass/category", __PRETTY_FUNCTION__] userInfo:nil]#define methodNotImplemented() mustOverride()

then in your methods you can use this

- (void) someMethod {     mustOverride(); // or methodNotImplemented(), same thing}



Notes: Not sure if making a macro look like a C function is a good idea or not, but I'll keep it until schooled to the contrary. I think it's more correct to use NSInvalidArgumentException (rather than NSInternalInconsistencyException) since that's what the runtime system throws in response to doesNotRecognizeSelector being called (see NSObject docs).