I want to go to there. Seriously though, how does one implement a pure virtual method in an "Apple" way? Do you use a Protocol with your base class and throw exceptions on those methods?
-
2It's a good question for people coming from a strong OO C++ background. – Andy Dent Jul 21 '13 at 21:23
6 Answers
When you program in Objective-C you need to purge your mind of such things as virtual methods. You don't call methods on Objective-C objects, you send messages to them. Objects either respond to messages or they don't, but due to the dynamic binding, you can't tell this until run time.
Thus, you can declare a method on a base object and not not provide an implementation, no problem (except for the compiler warning), but you can't have the compiler flag up when you directly instantiate an object with such methods and it won't throw an error at runtime unless you actually send that message to the object.
The best way to create "virtual" base classes (in my opinion) is to declare the method and give it a stub implementation that throws a suitable exception.

- 84,577
- 15
- 123
- 161
-
what is the convention of where I should declare the method to be implemented? do I put it in the superclass interface with a comment next to it? – João Portela Sep 29 '11 at 11:28
-
20Sorry, it's just silly to pretend that "sending messages" in ObjC is somehow magically different than function calling and needs its own name. Maybe it seemed that way back in the day, before we all learned how function binding doesn't have to be static, but today we all know that they're all just functions, regardless of the binding mechanism. – Glenn Maynard Aug 24 '12 at 23:47
-
9@GlennMaynard No, it is not silly. It's fundamental to the OO model that Objective-C inherited from Smalltalk. The selector and the method are different things. – JeremyP Aug 27 '12 at 10:31
-
15"Selectors" are nothing but first-class function signatures, and "sending a message" is nothing but finding and calling a function with that signature. It's all the same thing. – Glenn Maynard Aug 28 '12 at 00:17
-
4virtual method should look this: - (UIImage*)getImage{ @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] userInfo:nil]; } – evya Mar 12 '13 at 13:22
-
-
7@GlennMaynard I don't think anyone is pretending. They simply realize the subtle differences as they wrote lots of ObjC. It is *indeed* very similar to signature finding and method calling but **if you limit yourself to that model of thought you're just missing out on a lot of the niceties of ObjC.** "sending a message" is _much_ more than finding and calling a function with that signature. For example, you can have things like NSProxy that transforms message passing through them, or JSON parser pseudo-object that treat getter messages (non-existent methods) as access to JSON hash key values. – chakrit Mar 27 '13 at 06:06
-
From Antony Clements: Put this code in the implementation of the base class: [self doesNotRecognizeSelector:_cmd]; As noted by Apple, here: https://developer.apple.com/library/mac/#documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html – Luc Bloom Jul 02 '14 at 08:53
In Objective-C, there is no pure virtual support as in C++.
A simulation would be that you declare a method in your interface but don't implement it in your .m file. Of course you'd get compiler warnings but IIRC you can turn those off. But you won't get warnings/errors if you don't overwrite them in the subclass, which you get in C++ (IIRC).
An alternative would be to implement them with just an NSAssert(NO, @"Subclasses need to overwrite this method");
body. Still, you'd only catch this at runtime, not compiletime.

- 90,870
- 19
- 190
- 224
Depending on what you're doing the delegate pattern may be more appropriate than a subclass, where the delegate is defined as id<YourDelegateProtocol>
. The compiler will generate a warning if the required methods in the delegate protocol are not implemented.
Subclassing is generally avoided in Objective-C since objects cannot inherit from multiple superclasses but they can implement multiple protocols.

- 13,093
- 3
- 33
- 27
-
2every object in Objective-C is a subclass of NSObject. So I'd say that Subclassing is pretty important, and not 'generally avoided'. It occurs every time I make a custom view, table, or controller. – Stephen Furlani Mar 07 '11 at 18:32
-
1@Stephen: True, but what is generally avoided is deep hierarchies of subclasses. It's used much less often than in languages like Java and C++ – JeremyP Mar 07 '11 at 20:12
-
@JeremyP, that's true. Personally, I think that's a good thing. – Stephen Furlani Mar 07 '11 at 20:20
-
2@Stephan Furlani not *every* class in objc is a subclass of NSObject. a) not all objc systems/libraries are derived or inherit from nextstep b) even when interfacing with Apple's libraries only, you can still encounter root classes in the wild (for various reasons); NSProxy is one public example of this. – justin Mar 08 '11 at 05:27
You should use the:
- (void)doesNotRecognizeSelector:(SEL)aSelector method.
As noted by Apple, here: https://developer.apple.com/library/mac/#documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

- 51,061
- 28
- 99
- 211

- 91
- 1
- 3
-
Working docs link: https://developer.apple.com/documentation/objectivec/nsobject/1418637-doesnotrecognizeselector?language=objc – Dimitar Nestorov Mar 14 '22 at 16:12
You have a few options, but you're on the right track.
ObjC doesn't support this directly, forcing subclasses to implement a protocol is the best way to check it at compilation.
'Secretly' implementing the method in the base class and asserting is what I do to confirm the subclasser has subclassed correctly at runtime. Some people have mixed feelings about assertions, or must leave them active, so that's not always a good solution.
You can also force subclasses use a specific class constructor and initialization sequence, then verify they have implemented everything required before returning an instance, in case compiler warnings don't cut it.
But ObjC is missing some lang features which allow clients to shoot themselves in the foot, or workaround what they wish so... you shouldn't get too stuck on enforcing it.
note: Exceptions are very uncommon (and a bit unsafe, too) in ObjC.

- 104,054
- 14
- 179
- 226
-
Exceptions are perfectly fine for throwing if a subclass fails to implement a method it is mandatory to do so. – JeremyP Mar 07 '11 at 20:15
-
1@JeremyP no, they're not unconditionally fine. in fact, you're asking for UB when the exception crosses module boundaries. anyone throwing an exception makes the (potentially false) assumption that the client has enabled support for objc exceptions in all modules. it's far safer and far more idiomatic to return 0 (and assert and/or log a message) if the client fails to meet the api's requirement(s). you'll not make friends with your clients if that ships -- even though *they* failed to meet your object's requirements. – justin Mar 08 '11 at 05:37
-
@JeremyP: Apart from the points Justin made, there's also the memory problem: if you're in a GC environment this is not an issue, but in a "traditional" reference counting environment you face the problem of memory leaks. Consider: Allocate an object, call a method "foo", release object. If "foo" now throws an exception the allocated object is never released. – DarkDust Mar 08 '11 at 08:35
-
@DarkDust, @Justin: this would be considered a programming error and therefore not really recoverable, much like a range exception or a null pointer dereference. Ideally, the program would terminate at that point, so memory leaks are not a concern. – JeremyP Mar 08 '11 at 13:04
-
@JeremyP: If all you want is app termination then yes, exceptions are fine *in this very scenario* (thrown when an unimplemented method is called). Let's just hope nobody catches it, though ;-) – DarkDust Mar 08 '11 at 13:16
-
@DarkDust: You'd have to say the same about an NSRangeException or a "does not respond to this selector" exception both of which are thrown by the runtime. – JeremyP Mar 08 '11 at 13:41
-
-
@JeremyP the OP never stated that the client's failure to implement the interface is fatal or not -- you can fail more gracefully than exceptions and abort/termination in most_real_world_cases. returning 0 is the primary indication to the client that something went wrong along the way. in most cases, it's better to let the client decide how to handle the situation -- they know the context of its invocation and consequences. meanwhile, you've done what you can by disallowing an object's use by returning 0. – justin Mar 08 '11 at 17:22
-
@JeremyP hypothetical question: why would throwing an exception be an improvement over termination from the call site in the cases where app termination is 'ideal'? – justin Mar 08 '11 at 17:25
-
@Justin: The OP wanted something equivalent to pure virtual functions. If such things aren't implemented be subclasses in C++ or Java, you will get a compiler error. The designer of the superclass is saying "suclasses *must* implement this method". If they don't it is a programming error, in much the same way that sending a message to an object to which it doesn't respond is a programming error, or indexing off the end of an array is a programming error. – JeremyP Mar 09 '11 at 11:01
A virtual method is a method whose behavior can be overridden within an inheriting class by a function with the same signature (i.e same name with same number of params and type of params).
Example:-
@implementation BaseClass
-(void)viewDidLoad
{
[self virtualMethod:123];
}
-(void)virtualMethod:(int)param
{
//implement this method in subclass
}
@end
////////////////////////////////////////////////////
@interface ChildClass:BaseClass
@end
@implementation ChildClass
-(void)virtualMethod:(int)param
{
NSLog(@"There is no keyword "Virtual" in Objective C.");
}
@end
Output:-
"There is no keyword "Virtual" in Objective C."

- 348
- 4
- 14