多態在OC中,是面向對象的特性。引用Charlie Calverts對多態的描述——多態性是允許你將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。在OC中的本質就是:允許將子類類型的指針賦值給父類類型的指針,再調用父類的方法,這個方法既可以是子類重寫過的(會執行子類的方法),也可以是父類方法中傳入id類型,從而達到多態的特性。
多態:同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。
OC中的多態:不同對象對同一消息的不同響應。
這裏詳細說明兩點:
1:父類定義了一個方法後,子類可以重寫該方法,使用時,如果把子類的對象賦值給父類類型指針時,那麼調用方法時,會響應子類的方法。
2:多態的實現,引入了一個非常重要且常見的數據類型:id類型,這是一個萬能指針,它可以指向任意的類型,其本質是一種動態檢查類型,編譯時並不知道其具體指向了什麼類型,那麼定義的時候就隨意的使用,當然爲了防止id指向的對象跟父類不對應或是對象的方法不存在,引入了幾種常見的檢查函數,實例中會詳解。
實例:
<textarea readonly="readonly" name="code" class="object-c">
父類Animal的.h文件:
#import <Cocoa/Cocoa.h>
@interface Animal : NSObject
@property (nonatomic,strong) NSString *name;
-(void)eat:(id)animal;
@end
父類Animal的.m文件:
#import "Animal.h"
@implementation Animal
-(void)eat:(id)animal{
//id 類型是萬能指針,可以指向任意的對象,實在使用中可以使用多種方法來檢測是否有這個對象或者有這個方法,
[animal run];
NSLog(@"%@在喫",_name);
}
@end
子類Dog的文件
.h文件:
#import "Animal.h"
@interface Dog : Animal
@end
.m文件:
#import "Dog.h"
@implementation Dog
-(void)run{
NSLog(@"狗在跑");
}
@end
子類Cat的文件
.h文件:
#import "Animal.h"
@interface Cat : Animal
@end
.m文件:
#import "Cat.h"
@implementation Cat
-(void)run{
NSLog(@"貓在跑");
}
@end
.main文件:
#import <Foundation/Foundation.h>
#import "Animal.h"
#import "Dog.h"
#import "Cat.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Animal * ani = [[Animal alloc]init];
Dog * dog = [Dog new];
dog.name = @"汪汪";
ani = dog;
//dog對象是否有run方法
[dog respondsToSelector:@selector(run)];
//dog對象是否是Animal的子類
[dog isKindOfClass:[Animal class]];
//dog是否是Animal類
[dog isMemberOfClass:[Animal class]];
NSLog(@"%d", [dog respondsToSelector:@selector(run)] );
NSLog(@"%d",[dog isKindOfClass:[Animal class]]);
NSLog(@"%d",[ani isMemberOfClass:[Animal class]]);
[ani eat:dog];
}
return 0;
}
</textarea>