用一句話概括就是:事物在運(yùn)行過(guò)程中存在不同的狀態(tài)好爬。先以教科書(shū)般舉例說(shuō)明,下文再舉一個(gè)花木蘭替父從軍的例子幫助大家理解. 多態(tài)的存在有三個(gè)前提:
1.要有繼承關(guān)系
2.子類要重寫父類的方法
3.父類引用指向子類對(duì),
但是其中又有很多細(xì)節(jié)需要注意井辜。首先我們定義兩個(gè)類,一個(gè)父類Animal,一個(gè)子類Cat金句。
父類Animal
@interface Animal : NSObject
- (void)eat;
- (void)run;
@end
@implementation Animal
- (void)eat;
{
NSLog(@"動(dòng)物在吃飯");
}
- (void)run;
{
NSLog(@"動(dòng)物在奔跑");
}
@end
子類Cat
@interface Cat : Animal
@property (nonatomic ,assign) NSInteger age;
- (void)catchMouse;
@end
@implementation Cat
- (void)eat
{
NSLog(@"貓?jiān)诔燥?);
}
- (void)run
{
NSLog(@"貓?jiān)诒寂?);
}
- (void)catchMouse
{
NSLog(@"貓抓老鼠");
}
@end
測(cè)試
- (void)viewDidLoad
{
[super viewDidLoad];
Animal *animal = [[Cat alloc] init];
[animal eat];
[animal run];
}
結(jié)果:
2018-10-22 11:00:58.816523+0800 Polymorphic[4372:1542859] 貓?jiān)诔燥?2018-10-22 11:00:58.816566+0800 Polymorphic[4372:1542859] 貓?jiān)诒寂?
以上的三段代碼充分體現(xiàn)了多態(tài)的三個(gè)前提错沃,即:
1、存在繼承關(guān)系
Cat類繼承了Animal類
2棕兼、子類要重寫父類的方法
子類重寫(override)了父類的兩個(gè)成員方法eat(),sleep()抵乓。其中eat()是非靜態(tài)的伴挚,sleep()是靜態(tài)的。
3灾炭、父類數(shù)據(jù)類型的引用指向子類對(duì)象茎芋。
測(cè)試類中Animal *animal = [[Cat alloc] init];語(yǔ)句在堆內(nèi)存中開(kāi)辟了子類(Cat)的對(duì)象,并把棧內(nèi)存中的父類(Animal)的引用指向了這個(gè)Cat對(duì)象蜈出。
到此田弥,滿足了Java多態(tài)的的必要三個(gè)前提。
那么多態(tài)有什么弊端呢铡原?有的皱蹦,即多態(tài)后不能使用子類特有的屬性和方法煤杀。往上面的代碼看,子類Cat有一個(gè)特有的屬性age; 并且還有一個(gè)特有的抓老鼠的方法- (void)catchMouse沪哺。但是在測(cè)試類中沈自,我們嘗試調(diào)用子類特有的方法- (void)catchMouse和打印子類特有的成員屬性age; 就會(huì)報(bào)錯(cuò)。
[animal catchMouse];
animal.age = 100;
原因就是多態(tài)的弊端辜妓,就是:不能使用子類特有的成員屬性和子類特有的成員方法枯途。
--------------------------------------------------華麗的分割線----------------------------------------------------------------------
如果在代碼執(zhí)行過(guò)程中還想使用Cat類中特有的屬性age和它特有的成員方法- (void)catchMouse了怎么辦呢?那我們就可以把這個(gè)父類引用指向了子類對(duì)象的家伙animal再?gòu)?qiáng)制變回Cat類型籍滴。這樣animal就是Cat類型的引用了酪夷,指向的也是Cat對(duì)象了,自然也能使用Cat類的一切屬性和一切的成員方法孽惰。
- (void)viewDidLoad
{
[super viewDidLoad];
Animal *animal = [[Cat alloc] init];
[animal eat];
[animal run];
Cat *cat = (Cat *)animal;
[cat catchMouse];
cat.age = 100;
}
很明顯晚岭,執(zhí)行強(qiáng)轉(zhuǎn)語(yǔ)句Cat *cat = (Cat *)animal;之后,ct就指向最開(kāi)始在堆內(nèi)存中創(chuàng)建的那個(gè)Cat類型的對(duì)象了勋功。這就是多態(tài)的魅力吧坦报,雖然它有缺點(diǎn),但是它確實(shí)十分靈活狂鞋,減少多余對(duì)象的創(chuàng)建片择,不用說(shuō)為了使用子類的某個(gè)方法又去重新再堆內(nèi)存中開(kāi)辟一個(gè)新的子類對(duì)象