筋トレ大好きな文系女学生のJava入門_コンストラクタ


はじめに

ここ一ヶ月ほど、腹斜筋重視に筋トレしているせいか、綺麗に線が入ってきました
綺麗に線が入っていると、筋肉を育てる想いがより一層高まりますよね〜。

独学でやってるので、「これはJavaやっていくにあたって役に立つ知識だぞ!!」というのがあれば、コメントして頂けるととても嬉しいです

生まれたばかりのインスタンス

これまでに学んできたことを活かして、Java仮想世界にインスタンスを自由自在に生み出すことができるようになった!

1 public class Main{
2   public static void main(String[] args){
3     MuscleBoy mb = new MuscleBoy();       //インスタンスを生成
4     mb.name = "ホエイ";           //初期値セット
5     mb.hp = 100;                         //初期値セット
6     MuscleGirl mg = new MuscleGirl();       //またインスタンスを生成     
7     mg.name = "アミノ";                    //また初期値
8     mg.hp = 100;                         //また初期値
9     Protein p = new Protein();             //インスタンスを生成
10    p.name = "プロテイン";                    //初期値
11    p.recover(mb);             //やっとメインプログラム
12    p.recover(mg);
13   }
14}

クラスを使ったプログラミングをやってみると、newでインスタンスを生成した後に必ずフィールドの初期値を代入している。
なぜなら、newで生み出したばかりのインスタンスのフィールド(nameやhp)には、なにもはいっていないから!

厳密に言えば、空っぽではなくて、初期値が設定されている

フィールドの初期値

int型,short型,long型等の数値の型  ------>     0    
char型(文字)--------------------------->     ¥u0000
boolean型----------------------------->      false
int[]型------------------------------->      null
String型------------------------------>      null 

でも、毎度フィールドに初期値を設定するのは少しめんどくささを感じたりする ・・。
それに、実際に大規模な開発を行う場合、クラスを作るにあたっては、自分以外の開発者がMuscleBoyやMuscleGirlのクラスを使うことも考えて置かなければならない。
その開発者が、うっかり忘れてしまったり、値を負の数にしてしまったりして、正しくHPに100を代入してくれるとは限らない!!

そんな時に備え、Javaはインスタンスが生まれた直後に自動実行される処理をするプログラムをもっている !!

コンストラクタ



1 public class MuscleBoy{
2   int hp;
3   String name;
4    
5   void run(){
6        System.out.println(this.name + "は走っている");
7   }
8   MuscleBoy(){
9         this.hp = 100;         //hpフィールドを100で初期化
10  }
11}

このクラスのrun()メソッドは、「誰かから呼ばれないと動かない」ものだが、
8行目のMuscleBoy()メソッドは、このクラスがnewされた直後に自動実行される!!!!!
このようなメソッドを、コンストラクタ (constructor)というのだ。
上記のMuscleBoy()メソッドは、コンストラクタとして定義されているため、newされると同時に自動でHPに100が代入される。そのため、MainメソッドでHPに初期値を代入する必要はない

1 public class Main{
2   public static void main(String[] args){
3     MuscleBoy mb = new MuscleBoy();                
4
5     System.out.println(mb.hp);   //すでにhpには100が代入されているため、画面に「100」と表示
6   }
7}

コンストラクタは、プログラマーが直接呼び出すものではない!

コンストラクタと見なされる条件
①メソッド名がクラスメイト完全に一緒
②メソッド宣言に戻り値が記述されていない(voidもダメ!)

コンストラクタの基本
1 public class クラス名{
2   クラス名(){
3    //ここに自動実行処理を記述
4   }
5}

コンストラクタに情報を渡す

前述では、自動的にMuscleBoyのHPが100になったので、今度は、毎回違った名前を引数で受け取れるようにする!

1 public class MuscleBoy{
2   int hp;
3   String name;
4
5   MuscleBoy(String name){           //引数として文字列を1つ受け取る
6     this.hp = 100;
7     this.name = name;
8    }
9}
1 public class Main{
2   public static void main(String[] args){
3     MuscleBoy mb = new MuscleBoy("ホエイ");    //コンストラクタに「ホエイ」が渡される
4
5     System.out.println(mb.hp);      //100と表示
6     SYstem.out.println(mb.name);  //ホエイと表示
7   }
8}

上記のような、MuscleBoyクラスを使う場合は、コンストラクタに渡す引数をnewする際に指定する!

オーバーロード

上記で作ったMuscleBoyクラスには、「文字列引数を1つ受け取るコンストラクタ」が定義されている。
コンストラクタを作ったことによって、インスタンスを生成するときには必ず名前を指定する必要が生じる!
引数無しで「new MuscleBoy();」を実行するとエラーになる

この問題は、「引数を受け取らないコンストラクタ」も同時に定義することで解決できる!
それがオーバーロード


1 public class MuscleBoy{
2   int hp;
3   String name;
4  
5   MuscleBoy(String name){  //以前からあったコンストラクタ1
6     this.hp = 100;
7     this.name = name;
8   }
9   MuscleBoy(){       //新しく作ったコンストラクタ2
10    this("Nothing");
11   
12  }
13}

同じメソッドだけど引数が異なるメソッドを複数定義することができる。
オーバーライドと同じ役割をする!!

1 public class Main{
2   pubic static void main(String[] args){
3     MuscleBoy mb1 = new MuscleBoy("ホエイ"); //文字列引数があるためコンストラクタ1が呼び出される
4
5     System.out.println(mb.name);   //画面に「ホエイ」と表示
6     MuscleBoy mb2 = new MuscleBoy();  //引数がないのでコンストラクタ2が呼び出される
7
8     System.out.println(mb2.name);  //画面に「Nothing」と表示
9   }
10}

this(引数)のthis()は同一クラスの別コンストラクトを呼び出すもの。