C#入門㉓ 継承 ── クラスの性質を、受けつぐ
前回は「コンストラクタ(作るときの初期設定)」をやりました。
今回は、オブジェクト指向の山場、継承(けいしょう)です。あるクラスの性質を、別のクラスが受けつぐ仕組みです。少し難しく感じるかもしれませんが、考え方はとても自然です。
継承とは、あるクラスの性質を引きつぎ、新しいクラスを作ることです。
似たようなクラスを、何度も書きたくない
たとえば、「会社員」と「学生」のクラスを作るとします。
class Employee // 会社員
{
public string Name { get; set; }
public int Age { get; set; }
public void Greet() { Console.WriteLine(Name + "です"); }
public string Company { get; set; } // 会社名
}
class Student // 学生
{
public string Name { get; set; }
public int Age { get; set; }
public void Greet() { Console.WriteLine(Name + "です"); }
public string School { get; set; } // 学校名
}
よく見ると、Name・Age・Greet() が、まったく同じです。会社員も学生も「人」なので、共通する部分が多いんですね。
これを2回書くのは、無駄です。もし Greet() を直したくなったら、2か所とも直すことに。クラスが増えれば、もっと大変になります。
「共通する部分は、1回だけ書いて、使い回したい」。それを実現するのが、継承です。
共通部分を、親クラスにまとめる
まず、共通する部分を「人(Person)」というクラスにまとめます。
class Person // 親クラス(共通部分)
{
public string Name { get; set; }
public int Age { get; set; }
public void Greet() { Console.WriteLine(Name + "です"); }
}
そして、会社員と学生は、この Person を受けつぎます。
class Employee : Person // Person を継承
{
public string Company { get; set; } // 会社員だけの追加部分
}
class Student : Person // Person を継承
{
public string School { get; set; } // 学生だけの追加部分
}
: Person の部分が、「Person を受けつぐ」という意味です。
これで、Employee と Student は、書いていないのに Name・Age・Greet() を持っています。Person から受けついだからです。
Employee taro = new Employee();
taro.Name = "山田"; // Person から受けついだ
taro.Company = "ネスト"; // Employee 自身のもの
taro.Greet(); // 山田です(Person から受けついだ)
共通部分は Person に1回書くだけ。会社員・学生は、自分だけの追加部分を書けばいい。すっきりしました。
親と子、という関係
継承の関係は、よく「親子」でたとえられます。
- 親クラス(基底クラス) … 受けつがれる元(Person)
- 子クラス(派生クラス) … 受けつぐ方(Employee、Student)
子は、親の性質を受けついで生まれ、さらに自分だけの個性(Company、School)を加えます。子は親のものを使えますが、親は子のものを知りません。現実の親子と、少し似ていますね。
「〜は、〜の一種である」
継承を使っていいかの判断は、シンプルな問いで分かります。
「子は、親の一種か?」
- 「会社員は、人の一種か?」→ はい。だから継承してOK
- 「学生は、人の一種か?」→ はい。OK
逆に、これは変です。
- 「会社は、人の一種か?」→ いいえ。だから Company を Person から継承するのはおかしい
「AはBの一種である」が成り立つときだけ継承する。これが、継承を正しく使うコツです。料理でいうなら「カレーは料理の一種」「ラーメンは料理の一種」——共通の「料理」から受けつぐ、という感じです。
なぜ、継承すると良いのか
継承の利点は、2つあります。
ひとつは、これまで見たとおり、共通部分を1回で書けること。重複が減り、直すときも1か所で済みます。
もうひとつは、変更に強いこと。「人」に共通の機能を足したくなったら、Person に1つ書くだけ。それを継承している会社員も学生も、自動でその機能を持ちます。1か所の変更が、全体に行きわたる。これは、大きなプログラムでとても効いてきます。
つまずきポイント
初心者がやりがちなのが、何でも継承でつなごうとすることです。
継承は便利ですが、「AはBの一種か?」が成り立たないのに無理につなぐと、かえって分かりにくくなります。
class Engine : Car // 「エンジンは車の一種」? → おかしい
エンジンは車の一種ではなく、車の部品です。こういう「持っている」関係(車はエンジンを持つ)は、継承ではなく、前にやったフィールドで表します。
class Car
{
public Engine engine; // 車は、エンジンを「持っている」
}
「一種である」なら継承、「持っている」ならフィールド。この区別が、きれいな設計の分かれ目です。
まとめ
継承は、あるクラスの性質を受けついで、新しいクラスを作る仕組み。
class Person { ... } // 親クラス(共通部分)
class Employee : Person { ... } // 子クラス(Person を受けつぐ)
- 共通部分を親にまとめ、子は受けつぐ
- 子は、親の性質+自分の個性を持つ
- 使うのは「子は親の一種である」が成り立つときだけ
- 「持っている」関係は、継承ではなくフィールドで
継承は、オブジェクト指向の大きな山場のひとつです。一度で完全に分からなくても大丈夫。「共通部分を、受けつぐ」——この感覚だけ、つかんでおいてください。

