在繼承之後,各個derived class的object往往會需要執行同一個base class裡的函式,然而在不同的derived class裡,執行該函式的方法可能不同;讓base class的函式得以在不同derived class裡有不同的方式其實現則稱Polymorphism。
舉例,base class為「圖形」,derived class有「方形」、「圓形」,「圖形」這class裡有draw()這個函式,「方形」、「圓形」雖都繼承了這個函式,但是要draw出圖形的方法卻不同,這問題則是Polymorphism要討論。
首先我們看一下底下的程式碼(接續繼承(Inheritance)中的範例)
main.cpp
#include <iostream> #include <iomanip> #include "GodStudent.h" using namespace std; int main(){ Student people("People", 60); Student *ppeople = &people; GodStudent heron("Heron", 100, 90); GodStudent *pheron = &heron; // base-class object people.print(); // static binding ppeople->print(); // dynamic binding // derive-class object heron.print(); // static binging pheron->print(); // dynamic binding // // pheron = &people; // this can not work ppeople = &heron; return 0; }
這範例中有兩件事情要說明:
- base-class pointer可以指向derive-class object,但derive-class pointer不能指向base-class object。因為derive-class object "is-a" base-class object,所以第一句敘述是對的,C++中會依照宣告的資料型態去操作資料,所以透過base-class pointer指向derive-class object的方法只能使用base-class中有定義的函式,而derive-class中新定義的函式便沒有辦法操控(像是這例子的getBaseScore()/setBaseScore())
- object後面加"."讀取函式的方法為static binding,透過pointer/reference的方法為dynamic binding。static binding可以在compile的時候即知道有無錯誤,dynamic binding則要到程式執行時才能知道有沒有問題。
為了解決能讓base-class pointer指向derive-class object也能使用derive-class中的函式之問題,我們要介紹"virtual"。
- virtual,在base class中在某函式定義前面加virtual,往後base-class pointer指向derive-class object時,仍可以呼叫到derive-class object的函式,例如print(),他即可呼叫derive-class的print(),得以印出baseScore。撰寫derive-class時,寫覆蓋過base-class中的virtual函式的動作稱為override。
- pure virtual,此方法只在base class中寫該函式的interface(header中的prototype),不寫inplementation,且在prototype最後、分號前加"= 0"。此方法達到兩件事情:
- 含有pure virtual函式的class稱為abstract class(反義為concrete class),只有抽象意義,不能產生instance。例如「二維」是abstract class,底下繼承的「方形」、「圓形」才是concrete class。
- 在直接或間接的derive class中要能生成instance(concrete class),必須完成所有pure virtual函式的implementation
如此一來,在上層的base class中定義pure virtual函式,待不同的derive class來implement,得以解決本文最初提出的問題。同時也架構起了OOP。
More: C++ How To Program (8th Edition) -- Chapter 13
No comments:
Post a Comment