.. from wiki
透過相同的界面進行不同的操作,多型可以應用在資料型別與方法上
書中的解釋更為簡單,Same name, Different Class,不同的類別,相同的名稱,舉個例子,就像是同樣都是叫,鴨子類別中的叫可能是呱呱呱,狗的類別的叫則是汪汪汪。
Animal.h
#import <Foundation/Foundation.h> @interface Animal : NSObject { NSString *_name; } -(void)bray; @endAnimal.m
#import "Animal.h" @implementation Animal -(void)bray { NSLog(@"A......"); } @endDuck.h
#import "Animal.h" @interface Duck : Animal @endDuck.m
#import "Duck.h" @implementation Duck -(void)bray { NSLog(@"Caw..Caw..Caw....."); } @endDog.h
#import "Animal.h" @interface Dog : Animal @endDog.m
#import "Dog.h" @implementation Dog -(void)bray { NSLog(@"Wow...Wow..www"); } @endmain.m
#import <Foundation/Foundation.h> #import "Animal.h" #import "Duck.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { id foo; //First subclass foo = [[Duck alloc]init]; [foo bray]; //Second subclass foo = [[Dog alloc]init]; [foo bray]; } return 0; }
輸出結果:
main.m 當中的 id 是objective-C中泛指所有類別的型別,在其他的語言中,如果沒有這種型別,id 改為 Animal一樣可以,而在Objective-C中兩者都可以使用。
foo變數先指到Duck之後指向Dog,雖然方法名稱都是一樣,但是會根據個別類別中的方法去表現。多型的優點就是,不需要取很多的方法名稱,鴨子叫,狗叫,貓叫...,只要執行時去判斷是哪個類別,在找出相對應的方法即可。
Dynamic typing, dynamic binding
前者是指在執行的過程中,物件動態決定屬於哪個類別,後者則是根據哪種類別去執行方法,用上述的例子來說明
foo = [[Dock] alloc] init]; // dynamic typing
[foo bray]; // dynamic binding
In runtime決定型別固然很強大,但也有缺點,首先在編譯時,complier無法檢查是否有相對應的方法存在,相反地,如果是用靜態型別 static typing,complier 會確保每個方法對應到正確物件,這可以讓我們在編譯時就發現錯誤而不是在執行的時候,因為你永遠不知道使用者會如何操作,意謂者你不可能測試完所有的可能 ; 再者,使用大量的 id,會讓程式的可讀性降低。
沒有留言:
張貼留言