独習C++

C++:9.継承と多態性を使ったオブジェクトの拡張

独習C++

C++におけるオブジェクト指向プログラミングでは、継承と多態性が非常に重要な概念です。これらは、コードの再利用性を高め、より柔軟で拡張性のある設計を可能にします。本記事では、継承と多態性の基礎から、それらを活用してオブジェクトを拡張する方法について詳しく解説します。サンプルコードと実行結果を通じて、技術的な内容をわかりやすく説明します。

継承とは?

継承(Inheritance)とは、既存のクラス(親クラスまたは基底クラス)から新しいクラス(子クラスまたは派生クラス)を作成するメカニズムです。これにより、親クラスのメンバー(フィールドやメソッド)を子クラスで再利用でき、コードの重複を避けることができます。

継承の基本構文

以下に、C++での継承の基本的な使い方を示します。ここでは、親クラスとして`Animal`クラスを作成し、子クラスとして`Dog`クラスを定義します。

#include <iostream>
using namespace std;

class Animal {
public:
    void makeSound() {
        cout << "Animal is making a sound" << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() {
        cout << "Dog is barking" << endl;
    }
};

int main() {
    Dog myDog;
    myDog.makeSound();  // "Dog is barking" と表示されます
    return 0;
}

この例では、`Animal`クラスの`makeSound()`メソッドが`Dog`クラスでオーバーライドされています。`Dog`クラスのインスタンス`myDog`が作成され、`makeSound()`が呼び出されると、`Dog`クラスのバージョンが実行されます。

多態性とは?

多態性(Polymorphism)は、同じインターフェースを通じて異なる型のオブジェクトに対して異なる動作を実行できるメカニズムです。特に、仮想関数(virtual function)を使うことで、派生クラスで独自の実装を提供しつつ、基底クラスのポインタや参照を使用して関数を呼び出すことができます。

仮想関数と多態性の例

次に、仮想関数を使った多態性の例を紹介します。この例では、親クラスの`Animal`に仮想関数`makeSound()`を定義し、それを子クラス`Dog`でオーバーライドしています。

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void makeSound() {
        cout << "Animal sound" << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "Dog barks" << endl;
    }
};

void playSound(Animal &animal) {
    animal.makeSound();  // 実行時に正しいメソッドが呼ばれます
}

int main() {
    Dog myDog;
    playSound(myDog);  // "Dog barks" と表示されます
    return 0;
}

この例では、`Animal`クラスの仮想関数`makeSound()`が`Dog`クラスでオーバーライドされています。`playSound()`関数は、基底クラスの`Animal`型の参照を受け取りますが、実際には`Dog`クラスのオブジェクトを渡しており、実行時に`Dog`クラスの`makeSound()`が呼ばれます。これが多態性の力です。

継承と多態性を使ったオブジェクトの拡張

継承と多態性を組み合わせることで、コードの拡張性を大幅に向上させることができます。特に、基底クラスに新しい機能を追加した場合でも、既存の派生クラスに影響を与えることなく、それらを柔軟に拡張できます。

新しい動物クラスの追加

次に、新しい派生クラス`Cat`を追加し、`Animal`クラスを拡張してみましょう。

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void makeSound() {
        cout << "Animal sound" << endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "Dog barks" << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        cout << "Cat meows" << endl;
    }
};

void playSound(Animal &animal) {
    animal.makeSound();  // 実行時に正しいメソッドが呼ばれます
}

int main() {
    Dog myDog;
    Cat myCat;

    playSound(myDog);  // "Dog barks" と表示されます
    playSound(myCat);  // "Cat meows" と表示されます
    return 0;
}

このように、`Cat`クラスを追加しても、既存のコードに変更を加えることなく、同じ`playSound()`関数を使用して、さまざまなオブジェクトの音を再生できます。これにより、コードの柔軟性と拡張性が大幅に向上します。

まとめ

この記事では、C++における継承と多態性の基本的な概念について説明しました。継承を使用すると、コードの再利用性が向上し、多態性を活用することで、実行時に正しいメソッドが呼び出される柔軟なプログラムを作成できます。これらの技術を駆使することで、より効率的でメンテナンスしやすいソフトウェアを開発できるようになります。

次回の記事では、さらに高度なC++のオブジェクト指向プログラミング技法や、デザインパターンについて詳しく掘り下げていきます。

購読
通知
0 Comments
Inline Feedbacks
View all comments