多重繼承時通常其中一個基底類別作為private實作體,而其它的用以表現完全的抽像介面。
考慮您有一個方法doRequest(),您事先並無法知道什麼型態的物件會被傳進來,或者是這個方法可以接受任何類型的物件,您想要操作物件上的某個特定方法,例如doSomething()方法,問題是傳進來的物件是任意的,除非您定義一個抽像類別並宣告doSomething()抽像方法,然後讓所有的類別都繼承這個抽像類別,否則的話您的doRequest()方法似乎無法實作出來,實際上這麼作也沒有價值。
您可以藉由多重繼承來解決這個問題,例如先定義一個抽像類別:
#ifndef IREQUEST
#define IREQUEST
class IRequest {
public:
virtual void execute() = 0;
};
#endif
假設您的類別是以下的SomeObject類別的子類別:
#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類別,例如:
#include "IRequest.h"
#include "SomeObject.h"
#include <iostream>
using namespace std;
class Welcome : public SomeObject, public IRequest {
public:
void execute() {
cout << "Welcome!!" << endl;
}
};
#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的實例,而不用知道傳入的物件到底是什麼類別的實例,使用下面這個程式來測試:
#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;
}
執行結果: