UML類別圖:Generalization vs Realization

某一個類別去繼承另一個,子類別(child class)在擁有父類別的屬性和行為下去擴展功能,在C++很單純定義兩者關係為繼承(inheritance)。如下圖一所示,在UML有以下兩種方式描述繼承,兩者主要差別在父類別。
  • Generalization
    • 實線
  • Realization
    • 虛線
    • 父類別必須是界面(interface)
圖一. UML繼承

Realization


請先思考什麼是界面(interface)?

在物件導向的定義,界面是一個抽象類別,設計一個界面類似於設計一個類別,但是它們的思考點有所不同。類別描述物件的屬性和行為,而界面是定義類別們統一行為,並且不會有詳細行為描述。界面是不被允許實例化,但你可以宣告空指標,或是將它綁定其中一個子類別。

例如:當主人叫動物們(雞,豬和狗)走路時,如何在C++實作界面?

這裡只解釋程式碼的一部分,我已經將完整新增在線上C++編譯器ideone,你無需安裝任何C++IDE,直接線上修改後跑程式,請在以下找子標題程式碼。

  • 首先,找出類別們的共同行為,實作一個界面。這裡的例子為走路,因此新增界面Animal,然後增加純虛擬函數(pure virtual function) walking 定義走路的指令。
    class Animal
    {
    public:
        virtual ~Animal(){}
        virtual void walking()=0;
    };
  • 接下來,新增繼承界面的子類別,並且實作界面的子類別。以下舉雞為例,這裡的walking描述雞用兩隻腳走路。

  • class Chicken:public Animal
    {
    public:
        virtual void walking()
        {
           printf("chickens walk on two leg\n");
        }
    };
    
  • 最後,擁有界面指標向量的類別可直接呼叫物件的虛擬方法,不需要是哪一個類別實作。由於界面不允許初始化,在程式某處產生向量容器界面指標Animal,然後將物件雞,豬和狗放入容器後,擁有此容器的類別如同下圖46-47行直接呼叫walking,讓容器所有動物開始走路。
圖二. 界面的呼叫

下圖三我簡單使用UML圖描述上述例子,若你將此例做一些改善,界面不但使程式碼能被重複使用,而且能降低你程式的相依性,尤其在使用者介面和低層的互動。如果有時間,我將獨立寫一篇文章如何善用界面。

圖三. 範例類別圖

程式碼

  • 編譯環境
    • Ideone 線上編譯器
    • 最低C++版本: C++ 11 

結果

圖三. 程式碼執行結果

Reference

  1. Abstract Class vs Interface in C++, stackoverflow
  2. http://stackoverflow.com/questions/12854778/abstract-class-vs-interface-in-c
  3. 接口(Java)
  4. http://zh.wikipedia.org/wiki/%E6%8E%A5%E5%8F%A3_%28Java%29
  5. How do you declare an interface in C++, stackoverflow
  6. http://stackoverflow.com/questions/318064/how-do-you-declare-an-interface-in-c

留言

這個網誌中的熱門文章

VirtualBox教學:重設硬碟(.vdi)大小(上)

VirtualBox教學:重設硬碟(.vdi)大小(下)

VirtualBox教學: 新增Windows7虛擬電腦(下)