【Java入門】継承とコンストラクタの呼び出し(super/this)

こんにちは! エンジニアの本多です。

Javaでは、コンストラクタは継承されませんがスーパークラスのコンストラクタを呼び出すことができます。

この記事では、

・コンストラクタとは
・コンストラクタと継承の関係
・superとは
・thisとは

という基本的な内容から、

・サブクラスからスーパークラスのコンストラクタの呼び方
・コンストラクタの注意点

などの応用的な内容に関しても解説していきます。

なお、Javaの記事については、こちらにまとめています。

目次

コンストラクタとは

コンストラクタとは、クラスのインスタンス生成時に実行されるメソッドで、主にそのクラスのメンバ変数を初期化するときに使用します。

コンストラクタはインスタンス生成時に呼び出される特別なメソッドで、通常のメソッド同様に引数を指定することも可能です。

コンストラクタは継承継承されない

コンストラクタとは、クラスがインスタンス化されるときに一度だけ呼び出されるメソッドです。

コンストラクタは継承されないので、使うときには注意が必要です。

次の例では、エラーが発生します。

class SuperClass {
  public SuperClass() {
    System.out.println("SuperClassのコンストラクタ");
  }
}

public class SubClass extends SuperClass{
  public SubClass() {
    SuperClass();
  }
}

実行結果:

SubClass.java:3: error: cannot find symbol

コンストラクタは通常のメソッドとは異なり、継承ができません。

ちなみに、voidをつけたりreturn命令を書くと、コンストラクタではなく通常のメソッドと認識されますので注意してください。

暗黙的コンストラクタとは

Javaのクラスには必ず1つ以上のコンストラクタが存在する必要があります。

しかし、宣言しなくてもエラーになりません。

宣言が無ければ、暗黙的に自動で空のコンストラクタが生成されます。

親クラスでコンストラクタを宣言しなければ、自動的に中身のないコンストラクタが生成されます。

コンストラクタを宣言しない場合の例を次のプログラムで確認してみましょう。

class SuperClass {
  public SuperClass() {
    System.out.println("スーパークラスのコンストラクタ");
  }
}

class SubClass extends SuperClass {
}

public class TestClass {
  public static void main(String[] args){
    SubClass s = new SubClass();
  }
}

実行結果:

スーパークラスのコンストラクタ

このプログラムでは、サブクラスに処理を書いていないので、スーパークラスのコンストラクタが呼ばれています。

明示的コンストラクタとは?

暗黙的コンストラクタに対して、明示的にコンストラクタを宣言することが可能です。

先に述べたように、クラス名と同名のメソッドを記述すれば、それがコンストラクタとして認識されます。それを明示的コンストラクタと呼びます。

コンストラクタは複数宣言可能

コンストラクタは、同じ名前で複数宣言することが可能です。

ただし、引数の型・数の組み合わせ(シグネチャ)が同じものを複数宣言してはいけません

以下は、シグネチャが異なるので問題ありません。

class SuperClass {
  public SuperClass() {
  }
  public SuperClass(int a) {
  }
  public SuperClass(String s) {
  }
}

次の例は同じシグネチャがあるのでエラーが発生します。

class SuperClass {
  public SuperClass() {
  }
  public SuperClass() {
  }
}

[実行結果]

error: constructor SubClass() is already defined in class SubClass

こちらも、引数の型と数が同じメソッドが2つ宣言されているのでエラーが発生します。。

class SuperClass {
  public SuperClass(int a) {
  }
  public SuperClass(int b) {
  }
}

[実行結果]

error: constructor SubClass(int) is already defined in class SubClass

superでスーパークラスのコンストラクタを呼び出す

superを使って、サブクラスからスーパークラスのコンストラクタを呼び出すことが可能です。

自動的に呼び出されるのは引数のないコンストラクタなので、引数のあるコンストラクタを呼び出すにはsuperを使う必要があります。

次のプログラムで確認してみましょう。

class SuperClass {
  public SuperClass() {
    System.out.println("引数なしコンストラクタ");
  }
  public SuperClass(String s) {
    System.out.println("引数ありコンストラクタ:" + s);
  }
}

class SubClass extends SuperClass {
  public SubClass() {
    super("スーパークラスへ送りたい文字列");
  }
}

public class TestClass {
  public static void main(String[] args){
    SubClass s = new SubClass();
  }
}

実行結果:

引数ありコンストラクタ:スーパークラスへ送りたい文字列

superの詳しい使い方はこちらの記事で解説しているので、ぜひ確認してください。

thisで自身のコンストラクタを呼び出す

自身のコンストラクタを呼び出すにはthisを使います。

thisの使い方を次のプログラムで確認してみましょう。

class SuperClass {
  public SuperClass() {
    System.out.println("引数なしコンストラクタ");
  }
  public SuperClass(String s) {
    System.out.println("引数ありコンストラクタ:" + s);
  }
}
 
class SubClass extends SuperClass {
  public SubClass() {
    this(1, 2);
  }
 
  public SubClass(int a, int b) {
      System.out.println("a + b = " + String.valueOf(a + b));
  } 
}

public class TestClass {
  public static void main(String[] args){
    SubClass s = new SubClass();
  }
}

実行結果:

引数なしコンストラクタ
a + b = 3

このプログラムでは、スーパークラスのコンストラクタが呼ばれた後に、サブクラスのコンストラクタがthisを使って呼ばれています。

thisについての詳しい使い方はこちらの記事で解説しているので、ぜひ確認してください。

superとthisの注意点

superやthisはコンストラクタの最初に書かなくてはいけません。

初めに書かなかった場合にエラーになることを次のプログラムで確認してみましょう。

class SubClass extends SuperClass {
  public SubClass() {
    System.out.println("hogehoge"); // thisより前に処理がある
    this(1, 2);
  }
}

実行結果:

SubClass.java:4: error: call to this must be first statement in constructor
this(1, 2);

初めに書かないとこのようにエラーが発生するので注意してください。

コンストラクタについてもっと詳しく知りたい方へ

この記事で使用した、コンストラクタのさまざまな使い方については、以下の記事にまとめていますので、ぜひ参考にしてくださいね!

まとめ

いかがでしたか?

今回はクラスの継承とコンストラクタの関係について解説しました。

superやthisを使ってコンストラクタを使いこなせるようになってください。

もし、コンストラクタと継承を忘れてしまったらこの記事を確認してくださいね!

この記事を書いた人

関西在住のITエンジニアです。普通の会社に勤務しながら、侍エンジニアのインストラクター、ライターとして活動しています。

目次