.. from wiki
透過相同的界面進行不同的操作,多型可以應用在資料型別與方法上
書中的解釋更為簡單,Same name, Different Class,不同的類別,相同的名稱,舉個例子,就像是同樣都是叫,鴨子類別中的叫可能是呱呱呱,狗的類別的叫則是汪汪汪。
Animal.h
#import <Foundation/Foundation.h>
@interface Animal : NSObject
{
NSString *_name;
}
-(void)bray;
@end
Animal.m#import "Animal.h"
@implementation Animal
-(void)bray
{
NSLog(@"A......");
}
@end
Duck.h#import "Animal.h" @interface Duck : Animal @endDuck.m
#import "Duck.h"
@implementation Duck
-(void)bray
{
NSLog(@"Caw..Caw..Caw.....");
}
@end
Dog.h#import "Animal.h" @interface Dog : Animal @endDog.m
#import "Dog.h"
@implementation Dog
-(void)bray
{
NSLog(@"Wow...Wow..www");
}
@end
main.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,會讓程式的可讀性降低。
沒有留言:
張貼留言