id类型可以用来存储属于任何类的对象。
例如:
#import <Foundation/Foundation.h>
@interface Fraction: NSObject
{
int numerator;
int denominator;
}
-(void) print;
-(void) setTo: (int) n over: (int) d;
-(double) converToNum;
-(int) numerator;
-(int) denominator;
-(void) add: (Fraction *)f;
-(void) reduce;
@end
@implementation Fraction
-(void) print
{
NSLog(@"%i/%i",numerator,denominator);
}
-(void) setTo: (int) n over: (int) d
{
numerator = n;
denominator = d;
}
-(double) converToNum
{
if(denominator != 0)
{
return (double) numerator/denominator;
}
else
{
return 1.0;
}
}
-(int) numerator
{
return numerator;
}
-(int) denominator
{
return denominator;
}
-(void) add: (Fraction *)f
{
numerator = numerator * f->denominator + denominator * f->numerator;
denominator = denominator * f->denominator;
}
-(void) reduce
{
int u = numerator;
int v = denominator;
int temp;
while(v != 0)
{
temp = u % v;
u = v;
v = temp;
}
numerator /= u;
denominator /= u;
}
@end
int main(int agrc, char * agrv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Fraction *myFraction = [[Fraction alloc] init];
Fraction *tempFraction = [[Fraction alloc] init];
[myFraction setTo:100 over: 200];
[tempFraction setTo:1 over: 3];
//[myFraction print];
[myFraction add: tempFraction];
[myFraction reduce];
id dataValue;
dataValue = myFraction;
[dataValue print]; //与[myFraction print]输出的结果一样
[myFraction print];//
[myFraction release];
[tempFraction release];
[pool drain];
return 0;
}
编译时和运行时检查:
在编译的时候,即使出现错误,编译器不会产生警告信息,因为编译其在处理源文件时并不知道储存在dataValue中的对象类型。
运行时,系统会检查存储在dataValue中的对象类型,并检查确定方法是否是该类中的一个方法,如果是,则运行正常,如果不是,则显示出错信息并终止程序。
动态类型:id 可以接受任何的数据类型,缺点就是容易发生运行时异常。
id定义的时候,不用加星号。 id a = b;
运行阶段,才能确定的类型。
动态绑定:程序运行过程中,一些id类型的类,会根据实际情况,进行响应的类分配。
运行阶段,才能确定调用的方法。