------ android培訓、java培訓、期待與您交流! ----------
OC基礎—三大特性之多態
三大特性之多態:多種形態的意思(對象),多態是有條件的:必須有繼承,沒有繼承就沒有多態。
基本使用:
#import <Foundation/Foundation.h>
// ***************Animal類****************
@interface Animal : NSObject
- (void)eat;
@end
@implementation Animal
- (void)eat
{
NSLog(@"Animal喫東西——————");
}
@end
//**************Dog類****************
@interface Dog : Animal
@end
@implementation Dog
- (void)eat
{
NSLog(@"Dog喫東西——————");
}
@end
int main( )
{
NSObject *n = [Animal new]; // 這也是多態
// 多種形態
Dog *d = [Dog new]; // Dog類型
// 多態:父類指針指向子類對象
Animal *a = [Dog new];
// 調用方法時會檢測對象的真實類型
[a eat]; // 調用Dog中的eat
return 0;
}
我們知道了多態的條件就是繼承,沒有繼承就沒有多態。
Animal *a = [Dog new];這就是多態:父類指針指向子類對象。
在調用方法時會自動檢測對象的真是對象,之後在真實對象中需找相應的方法。
使用注意:
Dog *d = [Animal new]; 這是將子類指針指向父類,這樣寫是不對的。可以說Animal是一個Dog麼?這是錯誤寫法,並不是多態。但是你這樣寫了,編譯器並不會報錯,應爲OC的弱語法緣故,哪怕是NSString *str = [Animal new];這樣寫,編譯器也不會報錯,但是我們要知道,這樣寫是不對的。
多態的好處:
給上面的代碼添加一個feed函數
void feed(Animal *a)
{
[a eat];
}
int main( )
{
Animal *aa = [Animal new];
feed(aa);
Dog *dd = [Dog new];
feed(dd);
return 0;
}
這樣就可以看出多態的好處:上面的feed函數,如果參數中使用的是父類類型,可以傳入父類、子類對象
侷限性:
在上面的代碼中Dog類中增加一個方法
- (void)run
{
NSLog(@"Dog跑起來了");
}
main函數中調用
Animal *animal = [Dog new];
[animal run];
編譯器是比較笨的,在animal調用run函數的時候,看到Animal *animal就會認爲animal真的是Animal類的,Animal中沒有run方法,這時編譯器會發出一個警告(OC弱語法),但是還是可以運行的。但是這是規範問題 ,不能這樣調用。
父類類型的變量 不能 用來調用子類方法(可以成功,但是不規範,不建議使用)
強制轉化可以:
Animal *animal = [Dog new];
// 將animal轉換成Dog *類型
Dog *dd = (Dog *)animal;
[dd run];
這樣就可以了。