oc 动态类型和动态绑定

id 是泛类型 (generic data type), 可以用来存放各种类型的对象, 使用 id 也就是使用“动态类型”。 

int main (int argc, const char * argv[]) {
       id graphics;
       graphics = [[Ellipse alloc] init];
       [graphics onDraw];
       [graphics release];
       graphics = [[Triangle alloc] init];
       [graphics onDraw];
       [graphics release];
return 0; }

说明:

把Graphics *改成id类型,程序运行的结果没有任何影响。 由于动态类型的关系,id 在执行时,Objective-C 的执行 环境会找出该 id 所代表的原来类型,所以根本没有所谓的 转型。id 并不是自动的转换成 Ellipse和 Triangle的父类,而是在执行期间, 由执行环境辨认出 id 实际代表的类型为 Ellipse还是Triangle。因此在这个例子中id 与Graphics没 有任何关系。


实例:

• 定义两个类:"矢量"和"标量"类。

• 矢量”即有方向和大小的量,如物理学中的“力”。标量 为没有方向只有大小量,如物理学中的“功”。



Vector.h文件:

@interface Vector : NSObject {
    double vec1;
    double vec2;
}
@property double vec1,vec2;
-(void)print;
-(void)setVec1:(double)v1 andVec2:(double) v2;
-(Vector *)add:(Vector *)v;
@end

Vector.m文件:

#import "Vector.h"
@implementation Vector
@synthesize vec1,vec2;
-(void) setVec1:(double) v1 andVec2:(double)v2 {
    vec1 = v1;
    vec2 = v2;
}
-(Vector *)add:(Vector *)v {
    Vector *result = [[Vector alloc] init];
    [result setVec1:vec1 + [v vec1] andVec2: vec2 +
     [v vec2]];
    return result;
}
-(void)print {
    NSLog(@"%g,  %g",vec1,vec2);
}
@end

Scalar.h文件:

@interface Scalar : NSObject {
       double scal;
}
@property double scal;
-(void)print;
-(void)setScal:(double)sval;
-(Scalar *)add:(Scalar *)s;
@end

Scalar.m文件:

#import "Scalar.h"
@implementation Scalar
@synthesize scal;
-(void)print {
       NSLog(@"%g", scal);
}
-(void)setScal:(double)sval {
scal = sval;
}
-(Scalar *)add:(Scalar *)s {
       Scalar *result  = [[Scalar alloc] init];
       [result setScal:scal + [s scal]];
       return result;
} @end

调用的main函数:

#import "Vector.h"
#import "Scalar.h"
int main (int argc, const char * argv[]) {
       Scalar *scA =[[Scalar alloc] init];
       Scalar *scB =[[Scalar alloc] init];
       Vector *vecA =[[Vector alloc] init];
       Vector *vecB =[[Vector alloc] init];
       id scAandB;
       id vecAandB;
       [scA setScal: 10.5];
       [scB setScal: 13.1];
       [vecA setVec1: 3.2 andVec2: 4.7];
       [vecB setVec1: 32.2 andVec2: 47.7];
       [vecA print];
       NSLog(@" + ");
       [vecB print];
       NSLog(@" = ");
       vecAandB = [vecA add: vecB];
       [vecAandB print];
       [scA print];
       NSLog(@" + ");
       [scB print];
       NSLog(@" = ");
       scAandB = [scA add: scB];
       [scAandB print];
       [scA release];
       [scB release];
       [scAandB release];
       [vecA release];
       [vecB release];
       [vecAandB release];
       return 0;
}
3.2,  4.7
+
32.2,  47.7
=
35.4,  52.4
10.5
+
13.1
= 23.6


小结

 scAndB和vecAndB对象都是动态类型,都可以调用以 "print"和"add"方法。

虽然id类型可以任何类型的对象,但是不要滥用,如果能够确定对象数据类型时候,要使用“静态类型”,“静态类型”在编译阶段检查错误,而不是在执行阶段。而且“静态类型”程序可读性好。 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值