©️

C++ クラス継承・包含

2024/10/03に公開

記事の概要

  • オブジェクト指向のプログラミング言語で定義するクラスの継承と包含についてまとめる
  • この記事ではC++でのクラスの継承と包含についてをまとめる

包含について

  • ほうがん
  • あるクラスの中に別のクラスのオブジェクトを持つ関係のこと
  • クラスが別のクラスを「部分」として含むような状態

包含のサンプルコード

#include <iostream>

class Engine {
public:
    void start() {
        std::cout << "エンジンが始動しました" << std::endl;
    }
    void stop() {
        std::cout << "エンジンが停止しました" << std::endl;
    }
};

class Car {
public:
    Car() {
        engine = new Engine(); // エンジンのインスタンスを生成
    }
    ~Car() {
        delete engine; // エンジンのインスタンスを削除
    }
    void run() {
        engine->start();
        std::cout << "車が走ります" << std::endl;
    }

private:
    Engine* engine; // Carクラスの中にEngineクラスのオブジェクトのポインタを持つ
};

int main() {
    Car myCar; // Carクラスのオブジェクトを作成
    myCar.run(); // 車を走らせる

    return 0;
}

継承について

スーパークラスとサブクラス

サブクラスはスーパークラスのすべてのメンバー(変数、メソッド)を継承する
それぞれの特徴は以下

  • スーパークラス(基底クラス・親クラス)
    • 一般的な特徴を持つクラス
  • サブクラス(派生クラス・子クラス)
    • スーパークラスを拡張し、特徴を持つクラス
    • スーパークラスのメソッドをオーバーライド(上書き)することができる

継承のサンプルコード

#include <iostream>

// スーパークラス: 動物
class Animal {
public:
    void eat() {
        std::cout << "食べます" << std::endl;
    }
};

// サブクラス: 猫
class Cat : public Animal {
public:
    void meow() {
        std::cout << "ニャー" << std::endl;
    }
    // オーバーライド
    void eat() {
        std::cout << "猫は魚を食べます" << std::endl;
    }
};

// サブクラス: 犬
class Dog : public Animal {
public:
    void bark() {
        std::cout << "ワンワン" << std::endl;
    }
};

int main() {
    Cat neko;
    Dog inu;

    neko.eat(); // 猫は魚を食べます
    neko.meow(); // ニャー

    inu.eat(); // 食べます
    inu.bark(); // ワンワン

    return 0;
}

実行結果

猫は魚を食べます
ニャー
食べます
ワンワン

継承と包含の使い分け

継承を使うべきケース:

  • クラス間に「is-a」関係がある場合(例: 猫は動物の一種)
  • 共通の属性やメソッドを複数のクラスで共有したい場合

包含を使うべきケース:

  • クラス間に「has-a」関係がある場合(例: 車はエンジンを持っている)
  • クラスの機能を他のクラスのオブジェクトに委譲したい場合

Discussion