継承の基本
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 48/104。
継承により、あるクラスが別のクラスのプロパティや振る舞いを受け継ぐことができます。継承元のクラスはベースクラス(または親クラス)、継承する側のクラスは派生クラス(または子クラス)と呼ばれます。
派生クラスを作成するには、コロンに続けてアクセス指定子と基底クラス名を記述します:
class Animal {
public:
std::string name;
void eat() {
std::cout << name << " is eating" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << name << " says woof!" << std::endl;
}
};Dogクラスは、Animalからのnameとeat()の両方にアクセスできるようになり、さらに独自のbark()メソッドも持っています。これが継承の本質です。既存のコードを再利用しながら、新しい機能を追加することです。
Dog myDog;
myDog.name = "Buddy";
myDog.eat(); // Animalから継承
myDog.bark(); // Dogで定義Animal の前にある public キーワードは、継承の種類を指定します。公開継承は、基底クラスのパブリックメンバが派生クラスでもパブリックのまま保持されることを意味します。これは最も一般的な形式であり、「is-a」関係をモデル化しています。つまり、Dog は Animal である という関係です。
チャレンジ
簡単継承の動作を実演する、シンプルな車両の階層構造を構築しましょう。ベースとなる Vehicle クラスと、それを拡張して特化した動作を持つ派生クラス Motorcycle を作成します。
コードは以下の3つのファイルに分けて構成します:
Vehicle.h: 以下の内容を持つベースクラスVehicleを定義します:- パブリックな
std::string brandメンバ - パブリックな
int yearメンバ - 車両のブランドと年を
Brand: <brand>, Year: <year>という形式で出力するパブリックメソッドdisplayInfo()
- パブリックな
Motorcycle.h:Vehicleをパブリック継承するMotorcycleクラスを定義します。この派生クラスには以下を追加してください:- エンジンの排気量を表すパブリックな
int engineCCメンバ <brand> goes vroom vroom!と出力するパブリックメソッドrevEngine()
Motorcycleクラスは、Vehicleからbrand、year、およびdisplayInfo()を自動的に継承します。- エンジンの排気量を表すパブリックな
main.cpp: 3つの入力(それぞれ別々の行)を読み取ります:- ブランド名 (string)
- 年 (integer)
- エンジンの排気量 (integer)
Motorcycleオブジェクトを作成し、継承されたメンバ(brandとyear)および自身のengineCCメンバを設定します。その後、継承されたメソッドとバイク固有のメソッドの両方を呼び出して、継承を実演してください。出力形式:
Brand: <brand>, Year: <year> Engine: <engineCC>cc <brand> goes vroom vroom!
例えば、入力が Harley、2022、1200 の場合:
Brand: Harley, Year: 2022
Engine: 1200cc
Harley goes vroom vroom!ヘッダーファイルにはインクルードガードを忘れずに含め、Motorcycleのヘッダーではベースクラスにアクセスするために #include "Vehicle.h" を使用してください。
チートシート
継承を使用すると、あるクラスが別のクラスからプロパティや振る舞いを取得できるようになります。継承される側のクラスは**基本クラス**(親)、継承する側のクラスは**派生クラス**(子)と呼ばれます。
派生クラスを作成するには、コロンに続けてアクセス指定子と基本クラス名を記述します:
class Animal {
public:
std::string name;
void eat() {
std::cout << name << " is eating" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << name << " says woof!" << std::endl;
}
};派生クラスは、基本クラスの公開メンバと、自分自身のメンバの両方にアクセスできます:
Dog myDog;
myDog.name = "Buddy";
myDog.eat(); // Animalから継承
myDog.bark(); // Dogで定義publicキーワードは公開継承を指定します。これは、基本クラスの公開メンバが派生クラスでも公開のまま維持されることを意味します。これは「is-a」関係を表現します。
自分で試してみよう
#include <iostream>
#include <string>
#include "Motorcycle.h"
using namespace std;
int main() {
string brand;
int year;
int engineCC;
cin >> brand;
cin >> year;
cin >> engineCC;
// TODO: Motorcycle オブジェクトを作成する
// TODO: その brand、year、および engineCC メンバを設定する
// TODO: displayInfo() を呼び出して継承された情報を表示する
// TODO: 次の形式でエンジン情報を出力する: Engine: <engineCC>cc
// TODO: revEngine() を呼び出してオートバイ特有の動作を実演する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス