C++ 介面(抽象類)
C++ 介面(抽象類)
介面描述了類的行為和功能,而不需要完成類的特定實現。
C++ 介面是使用抽象類來實現的,抽象類與資料抽象互不混淆,資料抽象是一個把實現細節與相關的資料分離開的概念。
如果類中至少有一個函式被宣告為純虛擬函式,則這個類就是抽象類。純虛擬函式是通過在宣告中使用 "= 0" 來指定的,如下所示:
class Box
{
public:
// 純虛擬函式
virtual double getVolume() = 0;
private:
double length; // 長度
double breadth; // 寬度
double height; // 高度
};
設計抽象類(通常稱為 ABC)的目的,是為了給其他類提供一個可以繼承的適當的基類。抽象類不能被用於例項化物件,它只能作為介面使用。如果試圖例項化一個抽象類的物件,會導致編譯錯誤。
因此,如果一個 ABC 的子類需要被例項化,則必須實現每個虛擬函式,這也意味著 C++ 支援使用 ABC 宣告介面。如果沒有在派生類中重寫純虛擬函式,就嘗試例項化該類的物件,會導致編譯錯誤。
可用於例項化物件的類被稱為具體類。
抽象類的例項
請看下面的例項,基類 Shape 提供了一個介面 getArea(),在兩個派生類 Rectangle 和 Triangle 中分別實現了 getArea():
例項
#include <iostream>
using namespace std;
// 基類
class Shape
{
public:
// 提供介面框架的純虛擬函式
virtual int getArea() = 0;
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// 派生類
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
class Triangle: public Shape
{
public:
int getArea()
{
return (width * height)/2;
}
};
int main(void)
{
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
// 輸出物件的面積
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
// 輸出物件的面積
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
}
當上面的程式碼被編譯和執行時,它會產生下列結果:
Total Rectangle area: 35 Total Triangle area: 17
從上面的例項中,我們可以看到一個抽象類是如何定義一個介面 getArea(),兩個派生類是如何通過不同的計算面積的演算法來實現這個相同的函式。
設計策略
面向物件的系統可能會使用一個抽象基類為所有的外部應用程式提供一個適當的、通用的、標準化的介面。然後,派生類通過繼承抽象基類,就把所有類似的操作都繼承下來。
外部應用程式提供的功能(即公有函式)在抽象基類中是以純虛擬函式的形式存在的。這些純虛擬函式在相應的派生類中被實現。
這個架構也使得新的應用程式可以很容易地被新增到系統中,即使是在系統被定義之後依然可以如此。