Object-Oriented Programming Language
        Chapter 9 : Polymorphism, Dynamic Typing, and Dynamic Binding




                            Atit Patumvan
            Faculty of Management and Information Sciences
                          Naresuan University
2



                                                            The Three Key Concepts


             •        Polymorphism: objects from different class can define
                      methods that share the same name

             •        Dynamic Typing: the determination of the class that an
                      object belongs to unit the program is executing.

             •        Dynamic Binding: the determination of the actual method to
                      invoke an object unit program execution time




Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University   Object-Oriented Programming Language
3



                          Polymorphism: Same Name, Different Class

Program 9.1 main.m
01: #import "Complex.h"
02:
03: @implementation Complex
                                                                              Complex
04:
05: @synthesize real, imaginary;                         real : double
06:                                                      imaginary : double
07: -(void) print
08: {                                                    print() : void
09:! NSLog (@" %g + %gi ", real, imaginary);             setReal(double) : void andImaginary(double) : double
20: }                                                    add(Complex) : Complex
21:
22: -(void) setReal: (double) a andImaginary: (double) b
23: {
24:! real = a;
25:! imaginary = b;
26: }
27:
28: -(Complex *) add: (Complex *) f
29: {
30:! Complex *result = [[Complex alloc] init];
31:! result.real = real + f.real;
32:! result.imaginary = imaginary + f.imaginary;
33:! return result;
34: }
35: @end
Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University          Object-Oriented Programming Language
4



                          Polymorphism: Same Name, Different Class



                                                 Fraction                                                 Complex

                int : numerator                                                      real : double
                int : denominator                                                    imaginary : double

                print() : void                                                       print() : void
                setTo(int) over(int) : (void)                                        setReal(double) : void andImaginary(double) : double
                convertToNum : (double)                                              add(Complex) : Complex
                add(Fraction) : Fraction
                reduce() : void
Program 9.1 Fraction.m
  :
38: -(Fraction *) add: (Fraction * ) f
38: {
38:! Fraction * result = [[Fraction alloc] init];
38:! result.numerator = numerator * f.denominator + denominator                                            * f.numerator;
38:! result.denominator = denominator * f.denominator;
38:! [result reduce];
38:
38:! return result;
38: }
  :
Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                           Object-Oriented Programming Language
5



                          Polymorphism: Same Name, Different Class



                                                 Fraction                                                 Complex

                int : numerator                                                      real : double
                int : denominator                                                    imaginary : double

                print() : void                                                       print() : void
                setTo(int) over(int) : (void)                                        setReal(double) andImaginary(double) : double
                convertToNum : (double)                                              add(Complex) : Complex
                add(Fraction) : Fraction
                reduce() : void



Program 9.1 Complex.m
  :
38: -(Complex *) add: (Complex *) f
38: {
38:! Complex *result = [[Complex alloc] init];
38:! result.real = real + f.real;
38:! result.imaginary = imaginary + f.imaginary;
38:! return result;
38: }
  :
Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                          Object-Oriented Programming Language
6



                          Polymorphism: Same Name, Different Class

Program 9.1 main.m
  :
09:             Fraction *f1 = [[Fraction alloc] init];                                                    Complex
10:    !!       Fraction *f2 = [[Fraction alloc] init];
11:    !!       Fraction *fracResult;                                                real : double
12:    !!       Complex *c1 = [[Complex alloc] init];                                imaginary : double
13:    !!       Complex *c2 = [[Complex alloc] init];
14:    !!       Complex *compResult;                                                 print() : void
15:    !                                                                             setReal(double) : andImaginary(double) : double
16:    !!       [f1 setTo: 1 over: 10];                                              add(Complex) : Complex
17:    !!       [f2 setTo: 2 over: 15];
18:    !
19:    !!       [c1 setReal: 18.0 andImaginary: 2.5];                                                      Fraction
20:    !!       [c2 setReal: -5.0 andImaginary: 3.2];
  :    !
                                                                                     int : numerator
25:    !!       compResult = [c1 add: c2];
                                                                                     int : denominator
26:    !!       [compResult print];
  :    !                                                                             print() : void
36:    !!       fracResult = [f1 add: f2];                                           setTo(int) over(int) : (void)
37:    !!       [fracResult print];                                                  convertToNum : (double)
  :    !!                                                                            add(Fraction) : Fraction
                                                                                     reduce() : void




Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                   Object-Oriented Programming Language
7



                                              Dynamic Binding and the id Type

Program 9.2 main.m
  :
09:!      id dataValue;
10:!      Fraction *f1 = [[Fraction alloc] init];
11:!      Complex *c1 = [[Complex alloc] init];
12:
13:!      [f1 setTo: 2 over: 5];                                                                                      Fraction
14:!      [c1 setReal: 10.0 andImaginary: 2.5];
15:                                                                                             int : numerator
16:!      // first dataValue gets a fraction                                                    int : denominator
17:
18:!      dataValue = f1;                                                                       print() : void
19:!      [dataValue print];                                                                    setTo(int) over(int) : (void)
20:                                                                                             convertToNum : (double)
21:!      // now dataValue gets a complex number                                                add(Fraction) : Fraction
22:!      dataValue = c1;                                                                       reduce() : void
22:!      [dataValue print];
23:!
24:!      [c1 release];
25:!      [f1 release];                                            dataValue                                f1
  :
                                                                                                                                  numerator = 2
                                                                                     Fraction@yyyy
                                                                                                                                 denominator = 5
                                                                                               id                                      Fraction@yyyy

Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                               Object-Oriented Programming Language
8



                                              Dynamic Binding and the id Type




              Fraction * f1 = [[Fraction alloc] init];
              id f2 = f1;



                                                  f1


                                                                                     Fraction@yyyy

                                        f2                                                  Fraction

                                                                                                        numerator = 2
                                                                        Fraction@yyyy
                                                                                                       denominator = 5
                                                                                            id
                                                                                                          Fraction@yyyy



Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                        Object-Oriented Programming Language
9



               Argument and Return Types with Dynamic Typing



                                                 Fraction                                                 Complex

                int : numerator                                                      real : double
                int : denominator                                                    imaginary : double

                print() : void                                                       print() : void
                setTo(int) over(int) : (void)                                        setReal(double) andImaginary(double) : double
                convertToNum : (double)                                              add(Complex) : Complex
                add(Fraction) : Fraction
                reduce() : void


              id add (id dataValue1, id dataValue2)
              {
                return [dataValue1 add: dataValue2];
              }




Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                          Object-Oriented Programming Language
10



                              Methods for Working with Dynamic Types


                                              Method                                                   Question or Action

    -(BOOL) isKindOfClass: class-object                                              Is the object a member of class-object or a descendant?


    -(BOOL) isMemberOfClass: class-object                                            Is the object a member of class-object?

                                                                                     Can the object respond to the method specified by
    -(BOOL) respondsToSelector:selector
                                                                                     selector?

    +(BOOL) instancesRespondToSelector: selector                                     Can instances of the specified class respond to selector?


    +(BOOL)isSubclassOfClass: class-object                                           Is the object a subclass of the specified class?


    -(id) performSelector: selector                                                  Apply the method specified by selector

                                                                                     Apply the method specified by selector, passing the
    -(id) performSelector: selector withObject: object
                                                                                     argument object.
    -(id) performSelector: selector withObject: object1                              Apply the method specified by selector with the
    withObject: object2                                                              arguments object1 and object2.
Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                             Object-Oriented Programming Language
11



                                                 Exception Handling Using @try

Program 9.4 main.m
01: #import "Fraction.h"
02:
03: int main (int argc, char *argv [])
04: {
05: ! NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
06:! Fraction *f = [[Fraction alloc] init];
07:! [f noSuchMethod];
08:! NSLog (@"Execution continues!");
09:! [f release];
10:! [pool drain];
11:! return 0;
12: }            $ ./main
                                    2012-04-08 12:36:14.589 main[4336:707] -[Fraction noSuchMethod]: unrecognized selector sent to instance
                                    0x10be0c210
                                    2012-04-08 12:36:14.590 main[4336:707] *** Terminating app due to uncaught exception
                                    'NSInvalidArgumentException', reason: '-[Fraction noSuchMethod]: unrecognized selector sent to instance
                                    0x10be0c210'
                                    *** First throw call stack:
                                    (
                                    !     0   CoreFoundation                      0x00007fff91708fc6 __exceptionPreprocess + 198
                                    !     1   libobjc.A.dylib                     0x00007fff9344dd5e objc_exception_throw + 43
                                    !     2   CoreFoundation                      0x00007fff917952ae -[NSObject doesNotRecognizeSelector:] +
                                    190
                                    !     3   CoreFoundation                      0x00007fff916f5e73 ___forwarding___ + 371
                                    !     4   CoreFoundation                      0x00007fff916f5c88 _CF_forwarding_prep_0 + 232
                                    !     5   main                                0x000000010bd37bf2 main + 194
                                    !     6   main                                0x000000010bd376d4 start + 52
                                    )
                                    terminate called throwing an exceptionAbort trap: 6

Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                                      Object-Oriented Programming Language
12



                                                     @try and @ catch Statement




                            @try {
                               statement          throw exception
                               statement
                               ...                                                    Exception

                            }
                            @catch (NSException *exception) {                        catch exception
                               statement
                               statement
                               ...
                            }




Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                Object-Oriented Programming Language
13



                                                 Exception Handling Using @try

Program 9.5 main.m
01: #import "Fraction.h"
02:
03: int main (int argc, char *argv [])
04: {
05:! NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
06:! Fraction *f = [[Fraction alloc] init];
07:
08:! @try {
09:! ! [f noSuchMethod];
10:! }
11:! @catch (NSException *exception) {
12:! ! NSLog(@"Caught %@%@", [exception name], [exception reason]);
13:! }
14:! NSLog (@"Execution continues!");
15:! [f release];
16:! [pool drain];
17:! return 0;
18: }

$ ./main
2012-04-08 12:45:32.562 main[4445:707] -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x10870c210
2012-04-08 12:45:32.564 main[4445:707] Caught NSInvalidArgumentException-[Fraction noSuchMethod]: unrecognized selector sent to
instance 0x10870c210
2012-04-08 12:45:32.564 main[4445:707] Execution continues!
$


Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University                        Object-Oriented Programming Language

Chapter 9 : Polymorphism, Dynamic Typing, and Dynamic Binding

  • 1.
    Object-Oriented Programming Language Chapter 9 : Polymorphism, Dynamic Typing, and Dynamic Binding Atit Patumvan Faculty of Management and Information Sciences Naresuan University
  • 2.
    2 The Three Key Concepts • Polymorphism: objects from different class can define methods that share the same name • Dynamic Typing: the determination of the class that an object belongs to unit the program is executing. • Dynamic Binding: the determination of the actual method to invoke an object unit program execution time Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 3.
    3 Polymorphism: Same Name, Different Class Program 9.1 main.m 01: #import "Complex.h" 02: 03: @implementation Complex Complex 04: 05: @synthesize real, imaginary; real : double 06: imaginary : double 07: -(void) print 08: { print() : void 09:! NSLog (@" %g + %gi ", real, imaginary); setReal(double) : void andImaginary(double) : double 20: } add(Complex) : Complex 21: 22: -(void) setReal: (double) a andImaginary: (double) b 23: { 24:! real = a; 25:! imaginary = b; 26: } 27: 28: -(Complex *) add: (Complex *) f 29: { 30:! Complex *result = [[Complex alloc] init]; 31:! result.real = real + f.real; 32:! result.imaginary = imaginary + f.imaginary; 33:! return result; 34: } 35: @end Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 4.
    4 Polymorphism: Same Name, Different Class Fraction Complex int : numerator real : double int : denominator imaginary : double print() : void print() : void setTo(int) over(int) : (void) setReal(double) : void andImaginary(double) : double convertToNum : (double) add(Complex) : Complex add(Fraction) : Fraction reduce() : void Program 9.1 Fraction.m : 38: -(Fraction *) add: (Fraction * ) f 38: { 38:! Fraction * result = [[Fraction alloc] init]; 38:! result.numerator = numerator * f.denominator + denominator * f.numerator; 38:! result.denominator = denominator * f.denominator; 38:! [result reduce]; 38: 38:! return result; 38: } : Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 5.
    5 Polymorphism: Same Name, Different Class Fraction Complex int : numerator real : double int : denominator imaginary : double print() : void print() : void setTo(int) over(int) : (void) setReal(double) andImaginary(double) : double convertToNum : (double) add(Complex) : Complex add(Fraction) : Fraction reduce() : void Program 9.1 Complex.m : 38: -(Complex *) add: (Complex *) f 38: { 38:! Complex *result = [[Complex alloc] init]; 38:! result.real = real + f.real; 38:! result.imaginary = imaginary + f.imaginary; 38:! return result; 38: } : Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 6.
    6 Polymorphism: Same Name, Different Class Program 9.1 main.m : 09: Fraction *f1 = [[Fraction alloc] init]; Complex 10: !! Fraction *f2 = [[Fraction alloc] init]; 11: !! Fraction *fracResult; real : double 12: !! Complex *c1 = [[Complex alloc] init]; imaginary : double 13: !! Complex *c2 = [[Complex alloc] init]; 14: !! Complex *compResult; print() : void 15: ! setReal(double) : andImaginary(double) : double 16: !! [f1 setTo: 1 over: 10]; add(Complex) : Complex 17: !! [f2 setTo: 2 over: 15]; 18: ! 19: !! [c1 setReal: 18.0 andImaginary: 2.5]; Fraction 20: !! [c2 setReal: -5.0 andImaginary: 3.2]; : ! int : numerator 25: !! compResult = [c1 add: c2]; int : denominator 26: !! [compResult print]; : ! print() : void 36: !! fracResult = [f1 add: f2]; setTo(int) over(int) : (void) 37: !! [fracResult print]; convertToNum : (double) : !! add(Fraction) : Fraction reduce() : void Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 7.
    7 Dynamic Binding and the id Type Program 9.2 main.m : 09:! id dataValue; 10:! Fraction *f1 = [[Fraction alloc] init]; 11:! Complex *c1 = [[Complex alloc] init]; 12: 13:! [f1 setTo: 2 over: 5]; Fraction 14:! [c1 setReal: 10.0 andImaginary: 2.5]; 15: int : numerator 16:! // first dataValue gets a fraction int : denominator 17: 18:! dataValue = f1; print() : void 19:! [dataValue print]; setTo(int) over(int) : (void) 20: convertToNum : (double) 21:! // now dataValue gets a complex number add(Fraction) : Fraction 22:! dataValue = c1; reduce() : void 22:! [dataValue print]; 23:! 24:! [c1 release]; 25:! [f1 release]; dataValue f1 : numerator = 2 Fraction@yyyy denominator = 5 id Fraction@yyyy Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 8.
    8 Dynamic Binding and the id Type Fraction * f1 = [[Fraction alloc] init]; id f2 = f1; f1 Fraction@yyyy f2 Fraction numerator = 2 Fraction@yyyy denominator = 5 id Fraction@yyyy Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 9.
    9 Argument and Return Types with Dynamic Typing Fraction Complex int : numerator real : double int : denominator imaginary : double print() : void print() : void setTo(int) over(int) : (void) setReal(double) andImaginary(double) : double convertToNum : (double) add(Complex) : Complex add(Fraction) : Fraction reduce() : void id add (id dataValue1, id dataValue2) { return [dataValue1 add: dataValue2]; } Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 10.
    10 Methods for Working with Dynamic Types Method Question or Action -(BOOL) isKindOfClass: class-object Is the object a member of class-object or a descendant? -(BOOL) isMemberOfClass: class-object Is the object a member of class-object? Can the object respond to the method specified by -(BOOL) respondsToSelector:selector selector? +(BOOL) instancesRespondToSelector: selector Can instances of the specified class respond to selector? +(BOOL)isSubclassOfClass: class-object Is the object a subclass of the specified class? -(id) performSelector: selector Apply the method specified by selector Apply the method specified by selector, passing the -(id) performSelector: selector withObject: object argument object. -(id) performSelector: selector withObject: object1 Apply the method specified by selector with the withObject: object2 arguments object1 and object2. Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 11.
    11 Exception Handling Using @try Program 9.4 main.m 01: #import "Fraction.h" 02: 03: int main (int argc, char *argv []) 04: { 05: ! NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 06:! Fraction *f = [[Fraction alloc] init]; 07:! [f noSuchMethod]; 08:! NSLog (@"Execution continues!"); 09:! [f release]; 10:! [pool drain]; 11:! return 0; 12: } $ ./main 2012-04-08 12:36:14.589 main[4336:707] -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x10be0c210 2012-04-08 12:36:14.590 main[4336:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Fraction noSuchMethod]: unrecognized selector sent to instance 0x10be0c210' *** First throw call stack: ( ! 0 CoreFoundation 0x00007fff91708fc6 __exceptionPreprocess + 198 ! 1 libobjc.A.dylib 0x00007fff9344dd5e objc_exception_throw + 43 ! 2 CoreFoundation 0x00007fff917952ae -[NSObject doesNotRecognizeSelector:] + 190 ! 3 CoreFoundation 0x00007fff916f5e73 ___forwarding___ + 371 ! 4 CoreFoundation 0x00007fff916f5c88 _CF_forwarding_prep_0 + 232 ! 5 main 0x000000010bd37bf2 main + 194 ! 6 main 0x000000010bd376d4 start + 52 ) terminate called throwing an exceptionAbort trap: 6 Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 12.
    12 @try and @ catch Statement @try { statement throw exception statement ... Exception } @catch (NSException *exception) { catch exception statement statement ... } Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language
  • 13.
    13 Exception Handling Using @try Program 9.5 main.m 01: #import "Fraction.h" 02: 03: int main (int argc, char *argv []) 04: { 05:! NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 06:! Fraction *f = [[Fraction alloc] init]; 07: 08:! @try { 09:! ! [f noSuchMethod]; 10:! } 11:! @catch (NSException *exception) { 12:! ! NSLog(@"Caught %@%@", [exception name], [exception reason]); 13:! } 14:! NSLog (@"Execution continues!"); 15:! [f release]; 16:! [pool drain]; 17:! return 0; 18: } $ ./main 2012-04-08 12:45:32.562 main[4445:707] -[Fraction noSuchMethod]: unrecognized selector sent to instance 0x10870c210 2012-04-08 12:45:32.564 main[4445:707] Caught NSInvalidArgumentException-[Fraction noSuchMethod]: unrecognized selector sent to instance 0x10870c210 2012-04-08 12:45:32.564 main[4445:707] Execution continues! $ Atit Patumvan, Faculty of Management and Information Sciences, Naresuan University Object-Oriented Programming Language