Mark
Mark

Reputation: 69920

Override a method in Objective-C

I'm trying to override a getter in Objective-C. I have two classes, First and Second, like:

First.h:

@interface First : MashapeResponse {
    NSString* message;
}

@property(readwrite, retain) NSString* message;

@end

First.m:

#import "First.h"

@implementation First

@synthesize message;

@end

Second.h:

#import "First.h"

@interface Second : First

-(NSString*) message;

@end

Second.m:

#import "Second.h"

@implementation Second

-(NSString*) message {
    return [NSString stringWithFormat:@"%@%@", @"Message is ", message];
}

@end

I'm trying to execute the following code, but it seems like the overridden method in Second is never executed.

First* first = [[First alloc] init];
[first setMessage:@"hello"];
NSLog(@"%@", [first message]); // "hello" expected

Second* second = (Second*) first;
NSLog(@"%@", [second message]); // "Message is hello" expected, but it's still "hello"

Upvotes: 1

Views: 238

Answers (3)

Carl Veazey
Carl Veazey

Reputation: 18363

In Objective-C, casts only make a statement to the compiler that an object is of a certain type. They do nothing to alter the actual object in any way. In down-casting first to a pointer to a Second instance, you have made an assertion to the compiler that is actually incorrect - because the object now pointed to by both first and second is still an instance of First. Hope this helps!

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

The problem is not with how you override, but with how you allocate:

Second* second = [[Second alloc] init];
second.message = @"Hello";
NSLog(@"%@", [second message]);

When you cast First* to Second*, the object remains what it was - an instance of First. You need to allocate an instance of Second in order to see your override work.

Upvotes: 1

Jordão
Jordão

Reputation: 56457

You're actually casting a First as a Second (which is bad form); but the underlying type is still First, that's why you see the original message (from First). Alloc a Second, and it should work as expected.

Upvotes: 4

Related Questions