3-7. インタフェース

公開日: 21:45 3. オブジェクト指向編/3-7. インタフェース


インタフェースはC++クラスの挙動や特性をクラスの特定の仕様に任せることなく記述します。 

C++のインタフェースは抽象化クラスによって実装されますが、実装の詳細は関連するデータと分離するというコンセプトであるデータ抽象化と抽象化クラスは混同されるべきではありません。

クラスは1つ以上の関数を純粋仮想関数とすることで抽象化されます。純粋仮想関数は宣言に"=0"と続けることで指定されます。
class Box
{
   public:
      // 純粋仮想関数
      virtual double getVolume() = 0;
   private:
      double length;      // boxの縦幅
      double breadth;     // boxの縦幅
      double height;      // boxの深さ
};

抽象化クラスの目的はクラスが継承できる適切な基底クラスを供給することです。抽象化クラスはオブジェクトのインスタンス化には使われず、インタフェースとしてのみ機能します。抽象化クラスのオブジェクトのインスタンス化を試みるとコンパイルエラーとなります。

従って、抽象化クラスのサブクラスをインスタンス化する必要がある場合、仮想関数が実装されてなければならず、これは抽象化クラスで宣言されたインタフェースを裏付けることになります。派生クラスで純粋仮想関数のオーバーライドに失敗し、クラスのオブジェクトのインスタンス化を試みるとコンパイルエラーとなります。

オブジェクトのインスタンス化に使用できるクラスを具象クラスと呼びます。

抽象化クラスの例

親クラス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 << "四角形の面積: " << Rect.getArea() << endl;

   Tri.setWidth(5);
   Tri.setHeight(7);
   // オブジェクトの面積を出力
   cout << "三角形の面積: " << Tri.getArea() << endl; 

   return 0;
}
上のコードをコンパイルし実行すると、次の結果が得られます。
四角形の面積: 35
三角形の面積: 17

抽象クラスがどのようにgetArea()に関してインタフェースを定義したか、他の2クラスで指定した形状の計算に異なるアルゴリズムを同じ名前で実装したことが確認できます。

戦略設計

オブジェクト指向システムは抽象化基底クラスを外部のアプリケーションに対して一般的・標準的なインタフェースを適切に供給するために利用します。そして、その抽象化クラスからの継承によって派生クラスは同様に動作するよう形成されます。

外部アプリケーションによってもたらされる(public関数などの)機能は抽象化基底クラスの純粋仮想関数として供給されます。これらの純粋仮想関数の実装はアプリケーションの指定する型に対応する派生クラスに備えられます。

このアーキテクチャはシステムが定義された後でも、システムへの新しいアプリケーションの追加を容易にします。
  • ?±??G???g???[?d????u?b?N?}?[?N???A

0 件のコメント :

コメントを投稿