C++中的多态和Objective-C中的“多态”
C++中的多态(两种):
编译时匹配:函数重载,依据成员函数的名字、形参类型、形参个数等不同来实现不同的函数调用匹配;
运行时匹配:虚函数,具体就是通过将父类或抽象类声明时成员函数声明为virtual,然后子类继承并实现,应用时,通过将子类对象地址赋给其父类类型的指针(注,抽象类不能实例化,即不能定义对象,但是可以定义指向该类类型的指针和引用),通过调用赋值后的父类指针指向的虚函数来达到调用不同子类对该虚函数的不同实现的目的。
C++中实现运行时多态使用virtual.
Obiective-C中实现“多态”使用protocol. 具体请看如下实例,(实例摘自《Objective-C Beginner's Guide》)
Printing.h
@protocol Printing -(void) print; @end
Fraction.h
#import <Foundation/NSObject.h> #import "Printing.h" @interface Fraction: NSObject <Printing, NSCopying> { int numerator; int denominator; } -(Fraction*) initWithNumerator: (int) n denominator: (int) d; -(void) setNumerator: (int) d; -(void) setDenominator: (int) d; -(void) setNumerator: (int) n andDenominator: (int) d; -(int) numerator; -(int) denominator; @end
Fraction.m
#import "Fraction.h" #import <stdio.h> @implementation Fraction -(Fraction*) initWithNumerator: (int) n denominator: (int) d { self = [super init]; if ( self ) { [self setNumerator: n andDenominator: d]; } return self; } -(void) print { printf( "%i/%i", numerator, denominator ); } -(void) setNumerator: (int) n { numerator = n; } -(void) setDenominator: (int) d { denominator = d; } -(void) setNumerator: (int) n andDenominator: (int) d { numerator = n; denominator = d; } -(int) denominator { return denominator; } -(int) numerator { return numerator; } -(Fraction*) copyWithZone: (NSZone*) zone { return [[Fraction allocWithZone: zone] initWithNumerator: numerator denominator: denominator]; } @end
Complex.h
#import <Foundation/NSObject.h> #import "Printing.h" @interface Complex: NSObject <Printing> { double real; double imaginary; } -(Complex*) initWithReal: (double) r andImaginary: (double) i; -(void) setReal: (double) r; -(void) setImaginary: (double) i; -(void) setReal: (double) r andImaginary: (double) i; -(double) real; -(double) imaginary; @end
Complex.m
#import "Complex.h" #import <stdio.h> @implementation Complex -(Complex*) initWithReal: (double) r andImaginary: (double) i { self = [super init]; if ( self ) { [self setReal: r andImaginary: i]; } return self; } -(void) setReal: (double) r { real = r; } -(void) setImaginary: (double) i { imaginary = i; } -(void) setReal: (double) r andImaginary: (double) i { real = r; imaginary = i; } -(double) real { return real; } -(double) imaginary { return imaginary; } -(void) print { printf( "%_f + %_fi", real, imaginary ); } @end
main.m
#import <stdio.h> #import "Fraction.h" #import "Complex.h" int main( int argc, const char *argv[] ) { // create a new instance Fraction *frac = [[Fraction alloc] initWithNumerator: 3 denominator: 10]; Complex *comp = [[Complex alloc] initWithReal: 5 andImaginary: 15]; id <Printing> printable; id <NSCopying, Printing> copyPrintable; // print it printable = frac; printf( "The fraction is: " ); [printable print]; printf( "\n" ); // print complex printable = comp; printf( "The complex number is: " ); [printable print]; printf( "\n" ); // this compiles because Fraction comforms to both Printing and NSCopyable copyPrintable = frac; // this doesn't compile because Complex only conforms to Printing //copyPrintable = comp; // test conformance // true if ( [frac conformsToProtocol: @protocol( NSCopying )] == YES ) { printf( "Fraction conforms to NSCopying\n" ); } // false if ( [comp conformsToProtocol: @protocol( NSCopying )] == YES ) { printf( "Complex conforms to NSCopying\n" ); } // free memory [frac release]; [comp release]; return 0; }
output
The fraction is: 3/10 The complex number is: 5.000000 + 15.000000i Fraction conforms to NSCopying