OC多态性浅析
小实验
假设有以下两个类classA与class B的声明与实现:
/// classA.h
#ifndef classA_h
#define classA_h
#import <Foundation/Foundation.h>
@interface classA : NSObject
-(void) printVar;
@end
#endif /* classA_h */
/// classB.h
#ifndef classB_h
#define classB_h
#import <Foundation/Foundation.h>
#import "classA.h"
@interface classB : classA
-(void) printVar;
@end
#endif /* classB_h */
/// classA.m
#import "classA.h"
@implementation classA
-(void) printVar
{
NSLog(@"You called classA's method!");
}
@end
/// classB.m
#import "classB.h"
@implementation classB
-(void) printVar
{
NSLog(@"You called classB's method!");
}
@end
在main中编写如下代码进行测试:
/// main.m
#import "classA.h"
#import "classB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
classB *a = [classA new];
classA *b = [classB new];
[a printVar];
[b printVar];
}
return 0;
}
这里我们声明了一个classB
类型的对象a,但是用classA
的构造器去初始化它;同时声明了一个classA
类型的对象b,但是用classB
的构造器去初始化它,那么执行代码,它们调用的究竟是哪一个类中的printVar
函数呢?
答案如下:
可见,a实际调用了classA
中实现的方法,而b实际调用了classB
中的方法。
这是因为在Objective-C中,方法的调用是根据对象的实际类型来确定的,而不是根据对象的声明类型(即变量的类型)来确定的。由于[classB new]
返回的是classB
类型的对象,所以对a调用printVar
方法时,会调用classB中重载的printVar
方法。
Objective-C中的多态性(Polymorphism)允许子类重写父类的方法,从而可以在运行时基于对象的实际类型选择不同的方法实现。这样可以实现更灵活和可扩展的代码设计。
与C++进行比较
在C++中,如果classB
是classA
的子类并且重载了classA
的一个方法,那么如果使用classA
类型的指针或引用指向一个classB类型的实例,并调用该方法,会根据指针或引用的静态类型(即声明类型)来决定调用哪个方法。
如果使用classA
类型的指针或引用指向一个classB
类型的实例,并调用重载的方法,那么实际调用的方法会根据指针或引用所指向的对象的动态类型(即运行时类型)来决定。
这就是C++的多态性(Polymorphism)概念,它允许通过基类的指针或引用来操作派生类的对象,并根据对象的实际类型调用合适的方法。与Objective-C类似,C++中的多态性可以实现灵活和可扩展的代码设计。