★クラスの継承★


それでは、オブジェクト指向プログラミングの特徴の1つ「継承」について説明します。

「継承」とは文字の見た目の通り「受け継ぐ」事です。

あるクラスの能力を受け継いだ新しいクラスを作る事が出来るのです。

「継承元」になるクラスを「基底クラス」「親クラス」「スーパークラス」などと呼びます。

「継承先」になるクラスを「派生クラス」「子クラス」「サブクラス」などと呼びます。

「基底クラス」で用意したメンバ変数やメンバ関数は「派生クラス」に受け継がれます。


継承基礎


1つ簡単なサンプルを用意します。

まずは「基底クラス」のみ宣言します。

<sample program cpp072-01>

#include <iostream>

class Base {
public:

    void Hello();
};

int main()
{
    Base base;

    base.Hello();

    return 0;
}

void Base::Hello()
{
    std::cout << "Hello" << std::endl;
}

<実行結果>

Hello
続行するには何かキーを押してください・・・

このBaseクラスを「基底クラス」とします。

Baseクラスを受け継ぐクラスをDerivedと言う名前で追加してみます。

<sample program cpp072-02>

#include <iostream>

class Base {
public:

    void Hello();
};

class Derived : public Base {

};

int main()
{
    Base base;

    base.Hello();

    return 0;
}

void Base::Hello()
{
    std::cout << "Hello" << std::endl;
}

<実行結果>

Hello
続行するには何かキーを押してください・・・

クラスの宣言時に、Baseクラスを継承するコードが書いてあります。

class Derived : public Base

「:(コロン)」の後ろに「public 基底クラス名」と書くと、「基底クラス」を継承すると言う意味になります。

「派生クラス」であるDerivedには中身が何も書かれていません。

しかし、Baseクラスは継承していますから、↓のように使えます。

<sample program cpp072-03>

#include <iostream>

class Base {
public:

    void Hello();
};

class Derived : public Base {

};

int main()
{
    Base base;

    base.Hello();

    Derived derived;

    derived.Hello();

    return 0;
}

void Base::Hello()
{
    std::cout << "Hello" << std::endl;
}

<実行結果>

Hello
Hello
続行するには何かキーを押してください・・・

Derivedクラスの実体を作り、Baseクラスから受け継いだ「Hello関数」を実行しました。

Derivedクラスには中身はありませんが、ちゃんとBaseクラスを受け継いでいるのが分かります。


派生クラス


「派生クラス」の方にプログラムを追加してみます。

<sample program cpp072-04>

#include <iostream>

class Base {
public:

    void Hello();
};

class Derived : public Base {
public:

    void World();
};

int main()
{
    Base base;

    base.Hello();

    Derived derived;

    derived.Hello();

    derived.World();

    return 0;
}

void Base::Hello()
{
    std::cout << "Hello" << std::endl;
}

void Derived::World()
{
    std::cout << "World" << std::endl;
}

<実行結果>

Hello
Hello
World
続行するには何かキーを押してください・・・

「派生クラス」のDerivedに、「World関数」を追加しました。

これはDerivedクラス独自の関数ですから、Baseクラスとは関係ありません。

このように、受け継いだメンバ変数やメンバ関数以外に、派生クラス独自のメンバ変数、メンバ関数を設定する事が出来ます。


is-a関係


「継承」を使おうと考えた時に「is-a関係」と言う考え方に照らし合わせてチェックするようにしましょう。

「A is-a B」と書くと「AはBです」と言う意味になります。

例えば、「犬は動物です」は違和感がありませんが、逆の「動物は犬です」だと意味が通りません。

また、全く異なるもので「ノートは死神です」とか「猫はバスです」とかもアウトです。

この時に「Aが派生クラス」で「Bが基底クラス」と考えれば良いです。

「動物クラス」から派生した「犬クラス」、「動物クラス」から派生した「猫クラス」と考えます。

動物クラス ---+--- 犬クラス ---+--- 柴犬
       |                |
       |                |
       |                |
       |        +--- コーギー
       |
       |
       +--- 猫クラス

こんなイメージですかね。

すべての継承がこのようにスッキリした形ではありませんが、なるべく分かりやすくイメージ出来るような継承を考えましょう。


次へ

戻る

目次へ