發新話題

C++ Gossip - 物件導向《多型》 多重繼承(二)

C++ Gossip - 物件導向《多型》 多重繼承(二)

多重繼承時通常其中一個基底類別作為private實作體,而其它的用以表現完全的抽像介面。

考慮您有一個方法doRequest(),您事先並無法知道什麼型態的物件會被傳進來,或者是這個方法可以接受任何類型的物件,您想要操作物件上的某個特定方法,例如doSomething()方法,問題是傳進來的物件是任意的,除非您定義一個抽像類別並宣告doSomething()抽像方法,然後讓所有的類別都繼承這個抽像類別,否則的話您的doRequest()方法似乎無法實作出來,實際上這麼作也沒有價值。

您可以藉由多重繼承來解決這個問題,例如先定義一個抽像類別:
  • IRequest.h
#ifndef IREQUEST
#define IREQUEST

class IRequest {
public:
    virtual void execute() = 0;
};

#endif
假設您的類別是以下的SomeObject類別的子類別:
  • SomeObject.h
#ifndef SOMEOBJECT
#define SOMEOBJECT

#include <iostream>
using namespace std;

class SomeObject {
public:
    virtual void someFunction() {
        cout << "do something" << endl;
    }

private:
    void otherFunction() {
         cout << "do other" << endl;
    }
};

#endif
為了滿足之前所提供的doRequest()的需求,您讓衍生類別同時繼承IRequest與SomeObject類別,例如:
  • Welcome.h
#include "IRequest.h"
#include "SomeObject.h"
#include <iostream>
using namespace std;

class Welcome : public SomeObject, public IRequest {
public:
    void execute() {
         cout << "Welcome!!" << endl;
    }
};
  • Hello.h
#include "IRequest.h"
#include "SomeObject.h"
#include <iostream>
using namespace std;

class Hello : public SomeObject, public IRequest {
public:
    void execute() {
         cout << "Hello!!" << endl;
    }
};
假設您設計了一個doRequest()方法,雖然不知道Hello與Welcome是什麼型態,但它們都繼承了IRequest,所以doRequest()只要知道IRequest定義了什麼公開介面,就可以操作Hello與Welcome的實例,而不用知道傳入的物件到底是什麼類別的實例,使用下面這個程式來測試:
  • main.cpp
#include <iostream>
#include "IRequest.h"
#include "Welcome.h"
#include "Hello.h"
using namespace std;

void doRequest(IRequest *request) {
     request->execute();
}

int main() {
    Welcome welcome;
    Hello hello;
   
    doRequest(&welcome);
    doRequest(&hello);
   
    return 0;
}
執行結果:
Welcome!!
Hello!!

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。