多態(tài)(父類指針指向子類對象)
1.代碼體現(xiàn):父類類型的指針指向子類對象;

2.好處:如果函數(shù)、方法形參中使用的是父類類型,就可以傳入父類、子類對象;

3.局限性:父類類型的變量不能直接調(diào)用子類特有的方法,必須強轉(zhuǎn)為子類類型后才能直接調(diào)用子類特有方法

4.代碼練習(xí):
#import <Foundation/Foundation.h>
@interface Animal : NSObject
- (void)eat;
@end
@implementation Animal
- (void)eat
{
NSLog(@"Animal---吃東西");
}
@end
@interface Dog : Animal
- (void)run;
@end
@implementation Dog
- (void)eat
{
NSLog(@"Dog---吃東西");
}
- (void)run
{
NSLog(@"狗跑起來了");
}
@end
@interface Cat : Animal
@end
@implementation Cat
- (void)eat
{
NSLog(@"Cat---吃東西");
}
@end
// 喂狗
void feed(Dog *d)
{
[d eat];
}
// 喂貓
void feed2(Cat *c)
{
[c eat];
}
// 由于喂狗和喂貓的代碼基本一致,所以考慮將其抽取到一個函數(shù)內(nèi)
// 多態(tài)的好處:如果形參中使用的是父類類型,就可以傳入父類、子類對象
void feed3(Animal *a)
{
[a eat];
}
int main()
{
/***************1.多態(tài)的基本使用******************/
// 多態(tài):父類指針指向子類對象
Animal *a = [Dog new];
// 調(diào)用方法時會動態(tài)檢測對象的真實類型,這里對象a的真實類型是Dog
[a eat]; // 輸出:Dog---吃東西
/***************2.OC的弱語法******************/
/* 注意點:
OC的弱語法:這里僅僅是一個警告(warning: incompatible pointer types initializing 'Dog *' with an expression of type 'Animal *' [-Wincompatible-pointer-types])
*/
// Dog *d = [Animal new]; // 雖然僅僅是一個警告,但是在意思上不合理(動物是狗)
// [d eat]; // 輸出:Animal---吃東西
/***************3.多態(tài)的好處******************/
// 多態(tài)的好處:如果形參中使用的是父類類型,就可以傳入父類、子類對象
Dog *d2 = [Dog new];
feed(d2);
Cat *c2 = [Cat new];
feed2(c2);
Dog *d3 = [Dog new];
feed3(d3);
Cat *c3 = [Cat new];
feed3(c3);
/***************4.多態(tài)的局限性******************/
Dog *dd = [Dog new]; // Dog類型
Animal *aa = [Dog new]; // Animal類型
// OC的弱語法: warning: 'Animal' may not respond to 'run'
// 對于編譯器來講,編譯器認(rèn)為aa的類型是Animal,這里[aa run]就會去Animal中找是否有run的具體實現(xiàn),沒有找到就會警告,但是
還是會運行成功,因為在運行是會動態(tài)檢測aa的真實類型(Dog),Dog類中有run方法的具體實現(xiàn),就能正常運行
// 多態(tài)的局限性:父類類型的變量不能用來調(diào)用子類特有的方法
// [aa run];
// 對于上面的問題,可以將aa強制轉(zhuǎn)換成Dog類型,編譯器就不會警告
Dog *dd = (Dog *)aa; // 將aa強制轉(zhuǎn)換成Dog *類型
[dd run];
return 0;
}