2014年10月8日水曜日

- コンストラクタ - Java

前回の「インスタンスとクラス」の補足。

補足といっても、内容は非常に重要なため、しっかり理解しておきたい。

コンストラクタとは…

new と同時に(インスタンス化)、実行されるメソッドのこと。

定義の決まりごとは
・メソッド名がクラス名と一致
・戻り値を記述しない
(コンストラクタが実行される際に渡して欲しい引数を、newするときに指定すればよい)



package blog;

public class Tomomi {

 int age;
 int mana;

 // インスタンス化(new)された直後に実行される処理を書いたメソッド
 Tomomi(){
  this.mana = 20;
  System.out.println("起きてすぐのマナの残量は"+ this.mana + "です");
 }

 // 引数を受け取る
 void study(int time){
  this.mana -= time;
  System.out.println("勉強して、マナが"+ this.mana + "になった" );
 }
 // 引数を受け取る
 void sleep (int time){
  this.mana += time;
  System.out.println("寝て、マナが"+ this.mana + "になった" );
 }
}

package blog;

public class main {

 public static void main (String []args){

  // インスタンス化
  Tomomi t = new Tomomi();

  // 引数を渡して、呼び出して実行
  t.study(9);
  t.sleep(7);
 }
}










Tomomi クラスの
 Tomomi( ) {

}
が、コンストラクトになっている。
これを見て、わかるように、コンストラクタは、mainクラスから、
newされるときに必ず最初に自動で実行される。
他のメソッドのように、直接呼び出すメソッドではない。

ただ、直接、情報を渡すこともできる。
定義の決まりごとの部分に、少し書いてある
「コンストラクタが実行される際に渡して欲しい引数を、newするときに指定すればよい」
これが、どういうことか実際にみてみると


package blog;

public class Tomomi {

 int age;
 int mana;

 // インスタンス化(new)された直後に実行される処理を書いたメソッド
 // newする際に、int型の引数を受け取る
 Tomomi(int mana){
  // 受け取った引数を フィールド変数 mana に代入
  this.mana = mana;
  System.out.println("起きてすぐのマナの残量は"+ this.mana + "です");
 }

 // 引数を受け取る
 void study(int time){
  this.mana -= time;
  System.out.println("勉強して、マナが"+ this.mana + "になった" );
 }
 // 引数を受け取る
 void sleep (int time){
  this.mana += time;
  System.out.println("寝て、マナが"+ this.mana + "になった" );
 }
}

package blog;

public class main {

 public static void main (String []args){

  // インスタンス化して、コンストラクタに情報を渡す
  Tomomi t = new Tomomi(20);

  // 引数を渡して、呼び出して実行
  t.study(9);
  t.sleep(7);
 }
}

実行結果はさきほどと、変わらない。

コンストラクタのオーバーロード

上の例を見返してみる。

Tomomiクラスは、int型の引数を1つ受け取るように定義されている。
(int型の引数が必ず必要!!)

しかし、同じ名前のクラスを、同時に定義できる。
以前、学んだ、オーバーロードを使う。



package blog;

public class Tomomi {

 int age;
 int mana;

 // インスタンス化(new)された直後に実行される処理を書いたメソッド
 // newする際に、int型の引数を受け取る
 Tomomi(int mana){
  // 受け取った引数を フィールド変数 mana に代入
  this.mana = mana;
  System.out.println("起きてすぐのマナの残量は"+ this.mana + "です");
 }

 // 引数を受け取らない
 Tomomi(){

  this.mana = 10;
  System.out.println("普段のマナの残量は" + this.mana + "です");
 }

 // 引数を受け取る
 void study(int time){
  this.mana -= time;
  System.out.println("勉強して、マナが"+ this.mana + "になった" );
 }
 // 引数を受け取る
 void sleep (int time){
  this.mana += time;
  System.out.println("寝て、マナが"+ this.mana + "になった" );
 }
}


package blog;

public class main {

 public static void main (String []args){

  // インスタンス化
  // 引数がないので、引数を受け取らないコンストラクタが呼び出される
  Tomomi t = new Tomomi();

  // 引数を渡して、呼び出して実行
  t.study(9);
  t.sleep(7);
 }
}










また、クラスは、インスタンス化するときに、何かしらのコンストラクタを実行する。
が、特例がある。
クラスに1つもコンストラクタが定義されていない場合は、
「引数なし、処理内容なし」のコンストラクタの定義が自動的に追加される。
(クラスとインスタンスのときに書いていたものが、これに該当する)


コンストラクタから、別のコンストラクタを呼び出す

重複する処理を使いたい場合など、別のコンストラクタから呼び出すことができる。


package blog;

public class Tomomi {

 int age;
 int mana;
 String name;

 // インスタンス化(new)された直後に実行される処理を書いたメソッド
 // newする際に、int型の引数を受け取る
 Tomomi(String name){
  // 受け取った引数を フィールド変数 mana に代入
  this.mana = mana;
  this.name = name;

  System.out.println("起きてすぐのマナの残量は"+ this.mana + "です");
  System.out.println(this.name + "1");
 }

 // 引数を受け取らない
 Tomomi(){
  // Tomomi(String name)のほうのコンストラクタを呼び出す
  this("ともみ");

  this.mana = 10;
  System.out.println("普段のマナの残量は" + this.mana + "です");
  System.out.println(this.name + "2");
 }
}

package blog;

public class main {

 public static void main (String []args){

  // インスタンス化
  // 引数がないので、引数を受け取らないコンストラクタが呼び出される
  Tomomi t = new Tomomi();

 }
}









わかりやすいように、コンストラクタの中の実行文に数字を入れた。

this("ともみ")
で、1つ目のコンストラクタは文字列「ともみ」を受け取って実行している。

注意点は
thisの後にクラス名ではなく、引数を書く!!


0 件のコメント:

コメントを投稿