オブジェクト指向プログラミングの画像

継承とは、クラス同士に「上下の階層関係」を定義することで、「下位のクラスは上位のクラスの属性や操作を利用できる」という性質を持たせる、というだけの考え方であり、基本はこれだけです。

また、言葉の定義として、このような継承の上下関係が成立しているときに、上のクラスをスーパークラス関係、下のクラスをサブクラス関係と呼称します。

例えば下記のような継承関係があるとします。

・人、学生、会社員という3つのクラスが存在している

・学生クラスは人クラスを継承している

・会社員クラスもまた人クラスを継承している

この例の場合、下記の関係が成立しているといえます。

・学生クラスは人クラスのサブクラス

・会社員クラスは人クラスのサブクラス

・人クラスは学生クラスと会社員クラスのスーパークラス

継承により直接得られるメリットは極めて簡単なものです。
それは単に「下位クラスは上位クラスのすべての性質、すなわち属性と操作をそのまま引き継ぎ、それを最初から自分が持っているものと同様に利用できる」というだけのことにほかなりません。

たとえば先ほどの例では、「学生は人のすべての性質を引き継ぐ」ものですし、「会社員は人のすべての性質を引き継ぐ」ものです。

人クラスの属性に「名前」や「誕生日」があった場合は、学生クラスや社会人クラスも属性として備えているものであり、人クラスのもっている関数は、学生クラスや社会人クラスも操作として備えているものである、ということです。

例えば、学生と会社員が下記のような属性や関数をもっているとします。

・学生
属性:名前、誕生日、学校名、学籍番号
関数:今日の年齢を答える、勉強する

・会社員
属性:名前、誕生日、会社名、社員番号、
関数:今日の年齢を答える、働く

継承がないと上記のように記述しないといけませんが、上記の二つのクラスでは「名前」「誕生日」「今日の年齢を答える」という共通しているものがあります。
それをスーパークラスにまとめると効率的です。

それをせず上記のように「同じものを複数の場所に書く」ことは、設計やプログラミングのスタイルにおいて、一般原則として避けるべきことです。

なぜならば、それは単純に二度手間になるわけですし、何よりも実際の開発においては、あとから修正しようとしたときにそのすべてに同一の修正を施さねばならないことを意味しているからです。

実際に、システムやプログラムというものは、しばしばあとから細々とした修正が入ることが普通です。
単なるバグ修正のみならず仕様変更や機能拡張など、修正が将来必要になる可能性はいくらでもあります。

そして、どの部分でそれが発生するかを特定して予見することは、およそ困難です。

このことから、自分が作成するプログラムやシステムは、常にあとからの変更の可能性があることを前提に作成する必要があります。

このことから継承を使わずに同じ定義を複数のクラスに書くことは、本質的に危険で不安定な結果を残すことになります。

先ほどの例では学生と会社員というわずか2つのサブクラスを例としてあげているだけですが、実際のシステムでは5つや6つ、あるいは10や20のサブクラスを持つようなクラス構造を定義することもあり得ます。

そしてそのような場合、それらを全部書き直すのはそれだけで大仕事になりますし、最悪の場合、それらの一部を書き忘れて古いものを残してしまうような可能性すらもあり得ます、

プログラムの一部を修正するようなケースの場合、そのシグネチャには変更を施さず、メソッドの中身だけを書き換えるということが割と普通にあります。
そのような場合、書き換え忘れで同一のシグネチャを持つ古いメソッドと新しいメソッドが混在していても、そのエラーの類はコンパイルではすぐには検出されず、一見正常に動作しているかもしれません。
あるいはそれが何か微妙な内部的な状態の差違に起因する致命的なエラーの遠因になる可能性もありますし、そのような場合、原因の究明はひどく困難であることにもなるでしょう。

いずれにせよ、同じ属性やメソッドを共有させず複数のクラスに書いておくようなことは、およそ百害あって一利もありません。

とりあえず単なる記述コードの節約という意味だけの目的のためにでも、上位クラスを定義して継承は積極的に自作のシステムの中に取り入れていくようにしましょう。