Why two methods with the same name (belonging to different class) should have same prototype while using dynamic typing and dynamic binding?

StackOverflow https://stackoverflow.com/questions/21231210

Question

Hi I'm a newbie to objective-C ,today I was learning the concept of dynamic typing and binding, all was well until I wrote and executed this program

#import <Foundation/Foundation.h>
@interface A:NSObject
@property int var;
-(int)add:(A*)argObj;
@end

@implementation A
@synthesize var;
-(int)add:(A *)argObj
{
    return (self.var + argObj.var);
}
@end


@interface B:NSObject
@property double var1;
-(double)add:(B *)argObj;
@end

@implementation B
@synthesize var1;
-(double)add:(B *)argObj
{
    return (self.var1 + argObj.var1);
}
@end    

int main()
{  
    @autorleaease{
        id data1, data2;
        A * aobj1 = [[A alloc]init];
        aobj1.var = 30;
        A * aobj2 = [[A alloc]init];
        aobj2.var = 50;
        data1 = aobj1;
        data2 = aobj2;
        NSLog(@"The sum of two A objs is : %i",[data1 add: data2]);// prints 80 which is correct

        B * bobj1 = [[B alloc]init];
        bobj1.var1 = 5.5;
        B * bobj2 = [[B alloc]init];
        bobj2.var1 = 5.5;
        data1 = bobj1;
        data2 = bobj2;
        NSLog(@"The sum of 2 B objs is : %f",[data1 add: data2]);// prints 0.0000 why so ????
    }
        return 0;
}

I got the output when I executed add method on class A objects however when I executed the add method on class B I got the wrong answer. Why is this??

And this is how my output looked . In the output the compiler warned me like this

main.m: In function 'main':
main.m:47:5: warning: multiple methods named '-add:' found [enabled by default]
     NSLog(@"The sum of two A objs is : %i",[data1 add: data2]);
     ^
main.m:8:1: note: using '-(int)add:(A *)argObj'
 -(int)add:(A*)argObj;
 ^
main.m:8:1: note: also found '-(int)add:(A *)argObj'
main.m:26:1: note: also found '-(double)add:(B *)argObj'
 -(double)add:(B *)argObj;
 ^
main.m:55:5: warning: multiple methods named '-add:' found [enabled by default]
     NSLog(@"The sum of 2 B objs is : %f",[data1 add: data2]);
     ^
main.m:8:1: note: using '-(int)add:(A *)argObj'
 -(int)add:(A*)argObj;
 ^
main.m:8:1: note: also found '-(int)add:(A *)argObj'
main.m:26:1: note: also found '-(double)add:(B *)argObj'
 -(double)add:(B *)argObj;
 ^

Executing the program....
$demo 
2014-01-20 04:06:05.788 demo[30357] The sum of two A objs is : 80
2014-01-20 04:06:05.789 demo[30357] The sum of 2 B objs is : 0.000000

The compiler was saying multiple methods exist but these methods are entirely belongs to different class and while we use dynamic typing and dynamic binding the call will get resolved properly right ?? So why am I getting an output like this? Thanks in advance.. :)

Was it helpful?

Solution

The problem is not really about dynamic binding (which works as expected) but about passing the parameters. Ambiguous selectors prohibit that the compiler knows which prototype to use.

Objective-C uses C's ABI for function/method calling and argument passing. The compiler has to know the types of the arguments. If an variable is not strongly typed the compiler can not look up the correct selector. If the parameters are not compatible (as in your case) this will lead to undefined behavior.

Edit: The compiler actually tells you all about the confusion:

> main.m:47:5: warning: multiple methods named '-add:' found
> NSLog(@"The sum of two A objs is : %i",[data1 add: data2]);
> [...] note: using '-(int)add:(A *)argObj'

This is for the first use when adding two As. The compiler informs you that it used the class A variant for the call which is, by coincidence, correct.

> main.m:55:5: warning: multiple methods named '-add:' found
> NSLog(@"The sum of 2 B objs is : %f",[data1 add: data2]);
> [...] note: using '-(int)add:(A *)argObj'

That's the second log call with two B objects. Again the compiler complains that there's the ambiguity with the two add: selectors and informs you that it, again, chose the A variant. This time that's the wrong option and you see the unexpected results during runtime.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top