3-2. 継承

公開日: 14:04 3. オブジェクト指向編/3-2. 継承



継承はオブジェクト指向プログラミングの重要なコンセプトです。継承によってあるクラスの視点から別なクラスを定義することができ、アプリケーションの開発や保守が容易になります。継承はコードの機能性の再利用の機会と、実装速度の向上を提供します。

クラスを作成するとき、全く新しいメンバ変数とメンバ関数を記述する代わりに、プログラマは既存クラスのメンバを継承して新しいクラスを設計することができます。この既存のクラスを基底クラスと呼び、新しいクラスを派生クラスと呼びます。 

継承の考えは関係性の実装です。例えば、哺乳類は動物、犬は哺乳類、従って犬は動物、のようになります。

基底クラスと派生クラス

クラスは1つ以上のクラスから派生されることが可能で、これは複数の基底クラスからデータと関数を継承することができることを意味します。派生クラスを定義するには、基底クラスを指定するためにクラス派生リストを使います。クラス派生リストは1つ以上の基底クラスの名前で、次の形式となります。
class derived-class: access-specifier base-class

access-specifier(アクセス指定子)はpublicprotectedprivateのいづれかであり、base-classは定義済みクラスの名前です。アクセス指定子が使われなければ、デフォルトでprivateとなります。 基底クラスShapeとその派生クラスRectangleを考えてみます。
#include <iostream>
 
using namespace std;

// 基底クラス
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};

// 派生class
class Rectangle: public Shape
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};

int main(void)
{
   Rectangle Rect;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   // オブジェクトの面積を出力
   cout << "総面積: " << Rect.getArea() << endl;

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

アクセス制御と継承

派生クラスは基底クラスのprivateメンバを除くすべてへアクセス可能です。従って、派生クラスのメンバ関数からアクセスされたくない基底クラスのメンバはprivateで宣言されます。 何がアクセス可能かアクセスタイプの違いをまとめると次のようになります。
アクセスpublicprotectedprivate
同じクラス内可能可能可能
派生クラスから可能可能不可
クラスの外から可能不可不可

派生クラスは次の例外を除き、基底クラスのすべてのメソッドを継承します。

  • コンストラクタ、デストラクタ、コピーコンストラクタ
  • 基底クラスのオーバーロードされた演算子
  • 基底クラスのフレンド関数


継承の種類

基底クラスからクラスを派生させるとき、基底クラスはpublic、protected、privateのいづれかによって継承されます。継承のタイプはアクセス指定子によって指定されます。

protected、private継承はほとんど使用されず、public継承が一般的に使われます。継承の異なるタイプの使用は、次のルールが適用されます。

  • public継承:publicな基底クラスからクラスを派生させるとき、基底クラスのpublicなメンバは派生クラスのpublicなメンバとなり、基底クラスのprotectedなメンバは派生クラスのprotectedなメンバとなります。基底クラスのprivateなメンバは派生クラスから直接アクセスはできませんが、基底クラスのpublicまたはprotectedなメンバの呼び出しを通してアクセスすることは可能です。
  • protected継承:protectedな基底クラスから派生させるとき、基底クラスのpublicまたはprotectedなメンバは派生クラスのprotectedなメンバとなります。
  • private継承: privateな基底クラスから派生させるとき、基底クラスのpublicまたはprotectedなメンバは派生クラスのprivateなメンバとなります。


多重継承

C++クラスは1つ以上のクラスからメンバを継承することができ、次のような構文になります。
class derived-class: access baseA, access baseB....
accessはpublic、protected、privateのいづれかであり、カンマで区切られた各基底クラスに与えられます。次の例を試してみましょう。
#include <iostream>
 
using namespace std;

// 基底クラスShape
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};

// 基底クラスPaintCost
class PaintCost 
{
   public:
      int getCost(int area)
      {
         return area * 70;
      }
};

// 派生クラス
class Rectangle: public Shape, public PaintCost
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};

int main(void)
{
   Rectangle Rect;
   int area;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   area = Rect.getArea();
   
   // 面積を出力
   cout << "総面積: " << Rect.getArea() << endl;

   // 塗装コストを出力
   cout << "塗装コスト: $" << Rect.getCost(area) << endl;

   return 0;
}
上のコードをコンパイルし実行すると、次の結果が得られます。
総面積: 35
塗装コスト: $2450
  • ?±??G???g???[?d????u?b?N?}?[?N???A

0 件のコメント :

コメントを投稿