こんにちは!ISAMU(@burlesca_isa)です!
今回の対象読者は
- コンストラクタは何となく分かるが、使いこなせていない方
Javaのコンストラクタを使いこなすために押さえるポイント
今回の記事で覚えるべきポイントは
- デフォルトコンストラクタは引数と実装がないコンストラクタのこと
- デフォルトコンストラクタは1つもコンストラクタがない時に自動的に追加される
- コンストラクタは継承されない
- インスタンス化すると、コンストラクタの1行目にsuper()が暗黙的に追加される
- 引数のあるコンストラクタが1つでも定義されている時は、引数のないコンストラクタを定義しなくてはならない
デフォルトコンストラクタ
クラスに1つもコンストラクタを定義しなかった場合に
自動的に追加されるコンストラクタのことです。
デフォルトコンストラクタの定義は
- 引数をもたない
- 実装は空
です。
クラス名(){};
のようなコンストラクタが自動的に追加されます。
注意したいのが、
コンストラクタが1つでも定義されていた場合は
デフォルトコンストラクタは追加されないことです。
デフォルトコンストラクタの動きを理解することが
継承のコンストラクタの動きを理解する時に必要な知識となります。
コンストラクタとオーバーロード
コンストラクタにはオーバーロードが適応できます。
オーバーロードとはインスタンス化する際に渡す、コンストラクタの引数を柔軟に行うためのものです。
引数について下記のいずれかが異なっていることが条件です。
- 引数のデータ型
- 引数の数
- 引数の順
オーバーロードとは、あくまでも引数が上記の条件で異なることです。
戻り値は変えるだけではオーバーロードにはなりません。
サンプルプログラム
出力結果
名前 : NoName
年齢 : 20
出身地 : 日本
----------------------
名前 : 佐藤
年齢 : 20
出身地 : 日本
----------------------
名前 : 伊藤
年齢 : 41
出身地 : 日本
----------------------
名前 : 田中
年齢 : 23
出身地 : 埼玉
----------------------
引数の数を変えたオーバーロードのサンプルプログラムです。
引数の数によって変数に格納されるデフォルト値が変化します。
継承したクラスのコンストラクタ
継承のコンストラクタの動きで重要なことが、
- コンストラクタは連鎖する
- コンストラクタは継承されない
コンストラクタは継承されない
コンストラクタは継承されないため、
スーパークラスに定義されているコンストラクタを使用するにはsuper()を使用します。
super()に引数を渡すと、スーパークラスのコンストラクタが実行されます。
例えば、スーパークラスのメンバ変数に値を渡したい時
super(引数リスト);
super()はコンストラクタの先頭に記述する必要があります。
サンプルプログラム
実行結果
Super コンストラクタ
sub コンストラクタ
コンストラクタは連鎖する
インスタンス化する際に、
サブクラスのコンストラクタには暗黙的にsuper()がコンストラクタの1行目に追記されます。
そのため、引数のないインスタンスがされた場合には、
[サブクラスのコンストラクタsuper()]→[スーパークラスの引数のないコンストラクタ]→[サブクラスの引数のないコンストラクタ]の順で実行されます。
サンプルプログラム
サンプルプログラムをみてみます。
実行結果
A
B
C
Cクラスをインスタンス化すると、
Cクラスのコンストラクタの1行目にsuper()が暗黙的に追加されます。
そのため、Bクラスの引数のないコンストラクタを探しに行きます。
Bクラスのコンストラクタの1行名にもsuper()が暗黙的に追加されているため、
Aクラスの引数のないコンストラクタを探しに行きます。
Aクラスにはスーパークラスはないため、
super()は追加されません。
printlnメソッドを実行し、クラスBのコンストラクタへ戻ります。
クラスBのplintlnメソッドを実行しクラスCのコンストラクタへ戻ります。
最後にCクラスのplintlnメソッドを実行し完了となります。
重要なポイントが
- 子クラスのコンストラクタにはsuper()が追加されるということ
- コンストラクタが1つでも定義されている場合はデフォルトコンストラクタは自動的に作成されないこと
です。
例えば、
サブクラスでは引数がなくてもインスタンス化できるコンストラクタがある かつ スーパークラスで引数があるコンストラクタだけが定義されている
場合は、エラーになります。
インスタンス化した時には、
サブクラスでは暗黙的にsuper()が実行され、
スーパークラスではデフォルトコンストラクタが作成されない
ためです。
これを回避するために、スーパークラスでは引数のないコンストラクタを定義する必要があります。