【はじめてのJava】引数付きのコンストラクタ【オブジェクトとクラス編】
はじめてのJava
このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。
オブジェクトとクラス編
オブジェクトとクラス編では、Javaを扱う上で非常によく出てくる「オブジェクト」や「クラス」について扱っていきます。
前回は「コンストラクタ」について扱いました。
今回は「引数付きのコンストラクタ」について扱います。
目次
引数のあるコンストラクタ
通常のメソッド同様、コンストラクタも引数を取ることができます。
コンストラクタを定義する際に引数を定義し、クラスのインスタンス化の際に引数をコンストラクタに渡せばOKです。
詳しく見ていきましょう。
引数付きのコンストラクタとは
前回説明した通り、コンストラクタはそのインスタンスの初期設定を行います。
前回のような、引数のないコンストラクタでは、インスタンス変数の値は常に固定値になります。
例えば、前回扱ったCarクラスは以下の通りになっていました。
前回のCarクラス
class Car{ double speed; String color; //↓コンストラクタ Car(){ this.color = "red"; } void accell(){ speed += 10; } //↓オーバーロードしたaccellメソッド void accell(int s){ if(s < 0){ //sが負の数だった場合、メソッドの処理を終了する return; } speed +=s; } }
この場合、colorの初期値は常にredになります。
初期値が常にredでいいならこれで問題ありません。
しかし、通常は初期値として好きなcolorを設定したいことが多いです。
そこで、引数付きのコンストラクタを作成します。
どのように作成するのか、前回作成したコンストラクタ付きのCarクラスをもとに具体的に見ていきましょう。
引数付きのコンストラクタの書き方
コンストラクタは一般にメソッドの一種と言われます。引数の書き方もメソッドと同じです。
引数付きのコンストラクタの書き方は以下の通りです。
/* クラス名 */(/* 引数のデータ型 */ /* 引数名 */){ //初期化の内容 }
例えば、Carクラスに、colorの初期値を設定するためのコンストラクタは次のようになります。
Car(String c){ this.color = c; }
これを使えば、インスタンス化の際にインスタンス変数の初期値を指定することができます。
以下のようなイメージです。
では、さっそくCarクラスにこれを組み込んで…と行きたいところですが、その前に、今後のことを考え、少しコードを変更します。
具体的には以下のように、コンストラクタの引数名をcからcolorに変更します。
Car(String color){ this.color = color; }
このコードを見て「あれっ?コンパイルエラーになるのでは?」と思った方もいると思いますが、このコードはコンパイルエラーにはなりません。
むしろJavaの慣例に従う場合、コンストラクタの引数名は設定するインスタンス変数名にそろえます。
詳しくは本記事最後のコラムに記載してありますので、そちらも併せてご覧ください。
本記事では以降、この慣例に合わせた形でソースコードを作成します。
具体例(Carクラスに組み込んでみる)
では、改めてCarクラスを先ほどのコンストラクタを使った形に変更しましょう。
Carクラスに変更を反映すると以下の通りになります。
class Car{ double speed; String color; //↓引数付きのコンストラクタ Car(String color){ //ここを変更 this.color = color; //ここを変更 } void accell(){ speed += 10; } //↓オーバーロードしたaccellメソッド void accell(int s){ if(s < 0){ //sが負の数だった場合、メソッドの処理を終了する return; } speed +=s; } }
これで、インスタンス化の際にcolorの初期値を指定することができるようになりました。
動作確認
では、実際に動作確認してみましょう。
MyCarDriveクラスを利用して動作を確認します。
今回のMyCarDriveクラスは以下の通りです。
public class MyCarDrive{ public static void main(String[] args){ //Car myCar = new Car(); //今回は↓のように変更 Car myCar = new Car("blue"); //設定したいcolorの値を引数に入れる //↑でインスタンス化したのみで、他に何も操作を行わない System.out.println(myCar.color); //myCarのcolorを確認 } }
前回同様、インスタンス化以外は何もしないままmyCarのcolorを表示しています。
実行結果は以下の通りです。
myCarのcolorが、インスタンス化の際に指定したblueになっていることが確認できます。
これで、インスタンス変数の初期値を設定することができるようになりました。
コラム:コンストラクタの引数名
Javaでは慣例として、コンストラクタの引数名は設定するインスタンス変数名とそろえます。
ここだけ聞くとある疑問が浮かびますが、先に具体例を見てみましょう。
今回のCarクラスの場合は、慣例に沿って書くと以下のようになります。
class Car{ String color; Car(String color){ this.color = color; } }
上の例は一見すると「3行目のインスタンス変数名と5行目の引数名が重複しているのでコンパイルエラーになる」ように見えます。
しかし、上記のコードはコンパイルエラーになりません。
これは下記のような背景があるためです。
※詳しくはthisについての記事で扱う予定です。「混乱しそう」という場合は後で理解すればOKです。「コンストラクタの時はthisを付けて区別すればOK」という点だけ抑えて先に進んでください。
- thisがついている場合はインスタンス変数を表す
- thisがついていない場合は
- スコープ内に同名のローカル変数があればそれを表す
- スコープ内に同名の変数が無ければインスタンス変数を表す
本連載でも上記の慣例に従って記載していきます。
ソースコード
今回使用したソースコードをまとめて記載します。2つのソースコードは同じディレクトリに配置する必要があります。
Car.java
class Car{ double speed; String color; //↓引数付きのコンストラクタ Car(String color){ //ここを変更 this.color = color; //ここを変更 } void accell(){ speed += 10; } //↓オーバーロードしたaccellメソッド void accell(int s){ if(s < 0){ //sが負の数だった場合、メソッドの処理を終了する return; } speed +=s; } }
MyCarDrive.java
public class MyCarDrive{ public static void main(String[] args){ //Car myCar = new Car(); //今回は↓のように変更 Car myCar = new Car("blue"); //設定したいcolorの値を引数に入れる //↑でインスタンス化したのみで、他に何も操作を行わない System.out.println(myCar.color); //myCarのcolorを確認 } }
まとめ
インスタンス変数の初期値を指定したい場合は、引数付きのコンストラクタを定義する
引数付きのコンストラクタでインスタンス化(new)を行う場合は、引数に初期値を指定する
慣例としてコンストラクタの引数名は設定するインスタンス変数名と同名にする
次回
次回はコンストラクタのオーバーロードについて扱います。
はじめてのJavaシリーズの目次はこちら
オブジェクトとクラス編はこちら