一
多态概述
多态指同一操作作用于不同的对象。能够有不同的解释。产生不同的执行结果。它是面向对象程序设计(OOP)的一个重要特征,动态类型能使程序直到执行时才确定对象的所属类。其详细引用的对象在执行时才干确定。
动态绑定能使程序直到执行时才确定调用对象的实际方法。
C++使用虚函数(虚函数表)来实现动态绑定,当基类对象的指针(或引用)指向派生类的对象时候,实际调用的是派生类相应的函数。
是动态语言,所以它具有动态类型和动态绑定的特性。Objective-c系统总是跟踪对象所属的类。对于类型的推断和方法的确定都是在执行时进行。 那Objective-c是怎么样实现多态特性的呢?
@interface Draw : NSObject
@property (nonatomic,strong) NSString *name;
- (void) Print;
- (void) draw;
@end
@implementation Draw
@synthesize name;
- (id) init
{
[super init])
{
self.name = @"Draw Demo";
}
return self;
}
- (void) draw
{
NSLog(@"Draw::draw.......");
}
- (void) Print
{
NSLog(@"i am %@.",self.name);
}
@end
@end
@implementation Circle
- (void) draw
{
NSLog(@"%@:draw circle",self.name);
}
@end
@interface Retangle : Draw
@end
@implementation Retangle
- (void) draw
{
[super draw]; //通过superkeyword能够调用基类的draw函数
NSLog(@"%@:draw retangle",self.name);
}
@end
我们定义了一个Draw基类。里面有一个数据成员name,和两个函数成员draw和Print,Circle和Retangle是从Draw派生的两个类,他们重写了基类Draw的draw方法。
Draw* base = [[Circle alloc] init];
[base draw]; //draw circle
NSLog(@"address:%@",base);
base = [[Retangle alloc] init];
[base draw]; //draw retangle
NSLog(@"address:%@",base);
[base Print];
15:34:41.648 duotaidemo[7718:303] Draw Demo:draw circle
2014-04-09 15:34:41.673 duotaidemo[7718:303] address:<Circle: 0x1002027a0>
2014-04-09 15:34:41.674 duotaidemo[7718:303] Draw::draw.......
2014-04-09 15:34:41.674 duotaidemo[7718:303] Draw Demo:draw retangle
2014-04-09 15:34:41.675 duotaidemo[7718:303] address:<Retangle: 0x100205e70>
2014-04-09 15:34:41.676 duotaidemo[7718:303] i am Draw Demo.
因为Retangele没有重写基类的Print函数,全部使用[base
Print]调用的是基类的方法。
同一时候通过address的输出发现base指向了两个不同的对象。
id base = [[Circle alloc] init];
[base draw]; //draw circle
NSLog(@"address:%@",base);
base = [[Retangle alloc] init];
[base draw]; //draw retangle
NSLog(@"address:%@",base);
objc.h 文件里关于NSObject的定义
<NSObject>
Class isa OBJC_ISA_AVAILABILITY;
typedef struct objc_class *Class;
{
Class isa;
...);
详见:http://opensource.apple.com/source/objc4/objc4-493.9/runtime/objc.h
its isa instance variable, inherited from the NSObject class. isa identifies the object's class; it points to a structure that's compiled from the class definition. Through isa, an object can find whatever information it needs at run timesuch as its place
in the inheritance hierarchy, the size and structure of its instance variables, and the location of the method implementations it can perform in response to messages.
struct objc_class {
Class isa; /* metaclass */
Class super_class /* 父类的地址 */
const char *name /* 类名称 */
long version /* 版本号 */
long info /* 类信息 */
long instance_size /* 实例大小 */
struct objc_ivar_list *ivars /* 实例參数列表*/
struct objc_method_list **methodLists /* 方法列表 */
struct objc_cache *cache /* 方法缓存 */
struct objc_protocol_list *protocols /* protocol链表*/
类对象是一个依据类定义生成的一个结构体,里面存储了类的基本信息,
如:类的大小,类的名称,类的版本号以及消息与函数的映射表等信息。类对象所保存的信息在程序编译时确定,在程序启动 时载入到内存中。
在Objective-c中,id类型是一种通用的指针类型。id类型能够用来指向属于不论什么类的对象(仅仅要该对象是属于NSObject即成体系)。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmd6aGVianV0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
= [[Circle alloc] init];
isa成员,訪问类对象所保持的类的信息,isa成员能够通过类对象获得当前实例能够訪问的消息列表。以及消息相应的函数地址。