Javaではクラスという型からインスタンスという実体を作成して、フィールドやメソッドを利用します。
そのインスタンスを生成する際に利用されるコンストラクタについて解説します。
もくじ
コンストラクタとは
コンストラクタはインスタンスを生成する際に処理を行うメソッドのようなものです。しかし、メソッドとは明確に区別されます。コンストラクタは通常、インスタンス生成時に状態(フィールド)の初期化を行うことを目的とします。(フィールドの初期化以外の目的でも利用する場合あり)
クラスからインスタンスを生成する際には、以下のような構文を記述します。
インスタンスの生成 | クラス名 インスタンス変数名 = new クラス名() ; |
---|---|
記述例 | Taiyaki taiyaki_anko = new Taiyaki() ; |
この構文の中で、インスタンスを生成する記述は「new クラス名()」の部分となります。この「new クラス名()」は言い換えると、「new コンストラクタ()」となります。
インスタンスの生成 | new コンストラクタ() |
---|
コンストラクタは引数を持つため()も必要です。()内に値や変数がない為、引数なしのコンストラクタとも表現できます。今までのインスタンス生成は全て引数なしのコンストラクタを利用しています。
通常、コンストラクタを呼び出して、インスタンス生成を行います。コンストラクタはメソッドのようなもので、プログラマーがコンストラクタを定義することもできます。
デフォルトコンストラクタ
インスタンス生成時にはコンストラクタを呼び出しますが、コンストラクタの定義を行っていませんでした。Javaではコンストラクタが定義されていない場合、デフォルトコンストラクタと呼ばれるコンストラクタが自動的に定義されます。逆に、コンストラクタを定義しなかった場合はデフォルトコンストラクタは定義されません。
コンストラクタを定義する
コンストラクタは以下のように定義します。繰り返しになりますが、コンストラクタを定義した場合、デフォルトコンストラクタは定義されません。
コンストラクタの定義 | アクセス修飾子 クラス名(引数){ 処理 ; } |
---|---|
記述例 | Taiyaki(String n){ nakami = n; } |
※クラス名がコンストラクタ名となります
※記述例では、アクセス修飾子は修飾子なしで定義しています
メソッドと違う点は「戻り値を持たない(voidもなし)」部分です。また、必ずコンストラクタの名前はクラス名と同一になります。
基本的に、コンストラクタは状態(フィールド)の初期化を行う目的で定義しますので、戻り値を持つことはできませんしvoidの記述も行いません。
オーバーロードで引数が異なるコンストラクタを複数定義することができます。
コンストラクタのルール
以下が、コンストラクタに関するルールの一覧です。
- 基本的にフィールドの初期化を目的とする
- 戻り値は持たない(voidもなし)
- コンストラクタ名はクラス名と同一
- コンストラクタが定義されていない場合は、デフォルトコンストラクタが自動的に定義される
- コンストラクタを定義した場合は、デフォルトコンストラクタは定義されない
- コンストラクタもオーバーロード可能
コンストラクタ サンプルプログラム
以下のプログラムを「Taiyaki3.java」「Number32.java」という名前でworkフォルダ内に保存します。
保存が完了したら、コマンドプロンプトを起動し、Number32.javaをコンパイルおよび実行をしてみましょう。※Taiyaki2.javaは作成済みの場合は、中身をコピーして記述を変更してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//たい焼きクラスの作成 class Taiyaki3{ //たい焼きの中身 private String nakami; //たい焼きのサイズ private String size ; //グラム数 private double gram ; /* コンストラクタでたい焼きの初期値を設定 中身は引数で初期化し、サイズは中、グラムは90がデフォルト */ Taiyaki3(String n){ nakami = n; size = "中"; gram = 90; } //たい焼きの中身を確認する void open(){ System.out.println("たい焼きの中身は" + nakami + "です"); System.out.println("たい焼きは" + gram + "g、サイズは" + size + "です"); } } |
1 2 3 4 5 6 7 8 |
class Number32{ public static void main(String[] args){ //引数ありのコンストラクタを利用してインスタンス生成 Taiyaki3 taiyaki = new Taiyaki3("あんこ"); //確認 taiyaki.open(); } } |
実行例
C:\work>javac Number32.java
C:\work>java Number32
たい焼きの中身はあんこです
たい焼きは90.0g、サイズは中です
※実行例はコンパイルおよび実行までの例を表示しています。
サンプルプログラムの補足
Taiyaki3.javaではコンストラクタを定義しています。コンストラクタ定義は以下の部分となります。
1 2 3 4 5 |
Taiyaki3(String n){ nakami = n; size = "中"; gram = 90; } |
コンストラクタ内の処理は、中身を引数で初期化し、サイズは”中”とグラムは90という値で初期化しています。
コンストラクタを定義した場合は、デフォルトコンストラクタは定義されませんので、Number32.java内で以下のように呼び出すとエラーとなります。
1 2 3 |
//引数に値を設定しない Taiyaki3 taiyaki = new Taiyaki3(); taiyaki.open(); |
実行例
C:\work>javac Number32.java
Number32.java:5: エラー: クラス Taiyaki3のコンストラクタ Taiyaki3は指定された型
に適用できません。
Taiyaki3 taiyaki = new Taiyaki3();
^
期待値: String
検出値: 引数がありません
理由: 実引数リストと仮引数リストの長さが異なります
エラー1個
※実行例はコンパイルおよび実行までの例を表示しています。
もし、引数ありでも引数なしでもインスタンス生成させる際には、以下のようなコンストラクタを追加で定義(オーバーロード)します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* コンストラクタでたい焼きの初期値を設定 中身は引数で初期化し、サイズは中、グラムは90がデフォルト */ Taiyaki3(String n){ nakami = n; size = "中"; gram = 90; } /* 引数なしのコンストラクタの場合は全て初期値を内部で設定 */ Taiyaki3(){ nakami ="あんこ"; size = "中"; gram = 90; } |
補足 コンストラクタを定義することの意義
基本的にコンストラクタはインスタンスの状態を初期化するために定義します。
インスタンスを生成する際に(=コンストラクタを呼び出す際に)、インスタンス内部で状態を決定するためにデータを渡してほしい際は、引数ありのコンストラクタを定義します。
逆に、インスタンスを生成する際に(=コンストラクタを呼び出す際に)、インスタンス内部で状態を決定する場合は、引数なしのコンストラクタを定義します。
以下がイメージ図です。
引数ありのコンストラクタのみ定義されており、呼び出し側で引数なしのコンストラクタを呼び出した場合
コンストラクタ 復習問題
- コンストラクタの説明として正しいものを選んでください。
- デフォルトコンストラクタの説明として正しいものを選んでください。
- クラスCarのコンストラクタ定義として正しい記述を選んでください。
- お疲れ様でした。
-
- コンストラクタは戻り値を指定できる
- コンストラクタは引数が指定できる
- コンストラクタ名は自由に設定できる
- コンストラクタは引数が異なっても一つしか定義できない
-
- デフォルトコンストラクタはプログラマーが定義することができる
- デフォルトコンストラクタは引数を持つ
- デフォルトコンストラクタはコンストラクタを定義しても、自動的に定義される
- デフォルトコンストラクタはコンストラクタを定義していない場合、自動的に定義される
-
int Car(){}
void Car(){}
Car(){}
car{}
まとめ
- コンストラクタはインスタンス生成時に処理を行う
- 基本的にはフィールドの初期化を目的として定義する
- 戻り値は指定できない(voidも指定できない)
- コンストラクタ名はクラス名と同じ名前となる
- オーバーロード可能
- コンストラクタを定義していない場合は、デフォルトコンストラクタが自動的に定義される
- コンストラクタを定義すると、デフォルトコンストラクタは自動的に定義されない