多態(tài)(父類指針指向子類對(duì)象)
1.代碼體現(xiàn):父類類型的指針指向子類對(duì)象;
2.好處:如果函數(shù)肮蛹、方法形參中使用的是父類類型勺择,就可以傳入父類、子類對(duì)象蔗崎;
3.局限性:父類類型的變量不能直接調(diào)用子類特有的方法酵幕,必須強(qiáng)轉(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(@"狗跑起來(lái)了");
}
@end
@interface Cat : Animal
@end
@implementation Cat
- (void)eat
{
NSLog(@"Cat---吃東西");
}
@end
// 喂狗
void feed(Dog *d)
{
[d eat];
}
// 喂貓
void feed2(Cat *c)
{
[c eat];
}
// 由于喂狗和喂貓的代碼基本一致,所以考慮將其抽取到一個(gè)函數(shù)內(nèi)
// 多態(tài)的好處:如果形參中使用的是父類類型缓苛,就可以傳入父類芳撒、子類對(duì)象
void feed3(Animal *a)
{
[a eat];
}
int main()
{
/***************1.多態(tài)的基本使用******************/
// 多態(tài):父類指針指向子類對(duì)象
Animal *a = [Dog new];
// 調(diào)用方法時(shí)會(huì)動(dòng)態(tài)檢測(cè)對(duì)象的真實(shí)類型邓深,這里對(duì)象a的真實(shí)類型是Dog
[a eat]; // 輸出:Dog---吃東西
/***************2.OC的弱語(yǔ)法******************/
/* 注意點(diǎn):
OC的弱語(yǔ)法:這里僅僅是一個(gè)警告(warning: incompatible pointer types initializing 'Dog *' with an expression of type 'Animal *' [-Wincompatible-pointer-types])
*/
// Dog *d = [Animal new]; // 雖然僅僅是一個(gè)警告,但是在意思上不合理(動(dòng)物是狗)
// [d eat]; // 輸出:Animal---吃東西
/***************3.多態(tài)的好處******************/
// 多態(tài)的好處:如果形參中使用的是父類類型笔刹,就可以傳入父類芥备、子類對(duì)象
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的弱語(yǔ)法: warning: 'Animal' may not respond to 'run'
// 對(duì)于編譯器來(lái)講,編譯器認(rèn)為aa的類型是Animal舌菜,這里[aa run]就會(huì)去Animal中找是否有run的具體實(shí)現(xiàn)萌壳,沒(méi)有找到就會(huì)警告,但是
還是會(huì)運(yùn)行成功日月,因?yàn)樵谶\(yùn)行是會(huì)動(dòng)態(tài)檢測(cè)aa的真實(shí)類型(Dog)袱瓮,Dog類中有run方法的具體實(shí)現(xiàn),就能正常運(yùn)行
// 多態(tài)的局限性:父類類型的變量不能用來(lái)調(diào)用子類特有的方法
// [aa run];
// 對(duì)于上面的問(wèn)題爱咬,可以將aa強(qiáng)制轉(zhuǎn)換成Dog類型尺借,編譯器就不會(huì)警告
Dog *dd = (Dog *)aa; // 將aa強(qiáng)制轉(zhuǎn)換成Dog *類型
[dd run];
return 0;
}