【Javaの勉強】継承

2019年3月4日

メソッド、インスタンス、コンストラクタ・・・ややこしい横文字に混乱している時にまたややこしい話になるのが継承という話です。継承のことについてメモがわりに少し書いてみます。

継承とは

継承とは、親クラス・子クラスというようにしてクラスに階層を持たせる機能です。例えば、このようにして記述します。

親クラスが「会社」を表す「Companyクラス」、その下に子クラスとして「プログラム課」を表す「ProgramSectionクラス」を作ります。ちなみに、親クラスをスーパークラス、子クラスを「サブクラス」と呼びます。

【構文(サブクラス)】

class サブクラス名 extends スーパークラス名{}

サブクラスにはスーパークラスの変数とメソッドが引き継がれます。ここの機能自体は、「継承」ということばからなんとなく想像できますよね。ただ、ここから先がややこしい問題なのです。

継承におけるコンストラタの呼び出し

例1のソースコードを実行させる際、呼び出し元が必要となります。コンストラクタですので、インスタンス化(new)するだけで、呼び出すことができます。

実行結果ゆったり株式会社
プラグラム課

このプログラムでは「ProgramSection section1=new ProgramSection();」でサブクラスのコンストラクタを呼び出しています。サブクラスのコンストラクタにあるのは「プログラム課」だけなので、「プログラム課」とだけ出力されそうなものですが、実際には「ゆったり株式会社 プログラム課」というように、スーパークラスのコンストラクタも実行されています。

このように、継承ではサブクラスのコンストラクタを呼び出した時にはスーパークラスのコンストラクタも呼び出されることになります。そして順番は「スーパークラス⇒サブクラス」の順番です。そもそもコンストラクタというのはインスタンス化されたときに強制的に実行されるものですので、「継承でのコンストラクタは全部実行されるもの」だということを覚えておけば良いと思います。

コンストラクタにはややこしい問題がもう一つあります。

コンストラクタに引数があるときの問題

コンストラクタに引数を使って、次の例のように「株式会社」の部分だけ固定にして、会社名は変数にしようとしたとします。そのために、スーパークラスのコンストラクタに引数を設定します。

スーパークラスのコンストラクタは「Company(String s)」、呼び出し元で「ProgramSection section1=new ProgramSection(“ゆったり”);」とします。こうすることで、「ゆったり」がスーパークラスのコンストラクタの引数sに渡されて、処理文のsへと代入され、「ゆったり株式会社」となる・・・というわけではなく、これではコンパイルエラーとなります。

よくよく考えてみれば、「ProgramSection section1=new ProgramSection(“ゆったり”);」はサブクラスを呼び出していますので、まずはサブクラスのコンストラクタを経由します。そのサブクラスのコンストラクタからスーパークラスのコンストラクタを呼び出すのですが、「ProgramSection()」というコンストラクタには引数がありません。そのためコンパイルエラーとなってしまいます。

キーワード「Super();」を使う

解決するためには「Super();」というキーワードを使用します。これは、スーパークラスのコンストラクタを呼び出すための記述で、「明示的にスーパークラスのコンストラクタを指定する」というふうに言われます。そして、このSuperの括弧内には「s」を記述して、変数を渡せるようにします。また、サブクラスのコンストラクタの引数にも同じく「String s」を記述します。

実行結果ゆったり株式会社
プラグラム課

こうすることで呼び出し元の引数をサブクラスを経由してスーパークラスへ渡すことができます。