すべてのクラスは必ずコンストラクタを定義しないといけないらしい
何も書いてなかったらjavaコンパイラが勝手に書いて付け加えるらしい
public class Map(){
...
Map(){
}
}
こんな風に。
ただ、今回Hero(String name){
を作ってしまった場合には、
Hero(){
もつくっとかないとほうぼうにエラーが出るみたいな?
Hero(String name){
this.hp=100;
this.name=name;
}
Hero(){
this.hp=100;
this.name="ダミー";
}
さて、this.hp=100;が2回繰り返されている。よろしくない。
→
Hero(String name){//コンストラクタその1
this.hp=100;
this.name=name;
}
Hero(){//コンストラクタその2
this("ダミー");//コンストラクタ1を呼び出す
}
このthis("ダミー")は「自分のコンストラクタ」という意味らしい
「自分のコンストラクタで引数を持つもの」にジャンプする
コンストラクタから自分の引数ありのコンストラクタを呼び出す
**02
さて、インスタンスは情報をそれぞれ別に持っていますね?
勇者A HP120
勇者B HP150
みたいに
しかし「チームのお金」にしたかったらstatic(みんなでお財布ひとつ)を使うらしい
スタティック
--->Main364.java
public class Main364 {
public static void main(String[] args) {
Hero h1=new Hero();
Hero h2 = new Hero();
System.out.println(h1.hp);
System.out.println(Hero.money);
h1.money +=1000;
System.out.println(h1.money);
}
}
→出力結果
100
0
1000
--->Main365.java
public class Main365 {
public static void main(String[] args) {
Hero h1=new Hero();
Hero h2 = new Hero();
Hero.money=1000;
System.out.println(Hero.money);
System.out.println(h1.money);
h1.money +=300;
System.out.println(h2.money);
}
}
staticにしておくと「そのクラスに1つ」になるらしい
Hero.money=1000;という書き方が一般的
Hero.money
h1.money
h2.money
が同一の箱になる
staticなものははじめからあるらしい
Heroを1つも生成していなくても
突然、
Hero.monery=100;
System.out.println(Hero.money);
と記述することなんかも可能である
Math.minなんかも実はこのstatic
これはぜんぶスタティックだったのでnewしないで使えた
↓
**02
スタティックのなかではthisが通らない
「クラスで唯一」といってるもののなかで、thisを使うことは出来ない
複数個つくられるフィールドを扱うことができないらしい
メソッドとなかみが「お揃い」である必要があるのだ
非スタティックをスタティックから参照しようとしているエラーがでるよ
メソッドにstaticがついていたら中身で扱うのもstaticでお揃いになるべきだし、
ぎゃくにvoidだったら中身はh1.nameとかが通るのだ
main371.javaを共有からdl
テスト用
aをつかいまわしてb,c,dをつくる
こうではない!!!↓
Cleric(String name,int hp,int mp){//(a)3つの引数があるクレリック
this.name = name;
this.hp = hp;
this.mp = mp;
}
Cleric(String name,int hp){//(b)2つの引数があるクレリック
this.name = name;
this.hp = hp;
this.mp = MAX_MP;
}
Cleric(String name){//(c)1つの引数があるクレリック
this.name = name;
this.hp = MAX_HP;
this.mp = MAX_MP;
}
だぶらせないように記述するのだ!!!
まず、3つぞろいのコンストラクタが「全条件設定パターン」なので、
2つぞろいや1つぞろい(引数が2つとか1つのバージョン)は、「3つぞろいのコンストラクタをよびだしてくれ」」という記述にするのだ
『もう一つの意味のthis』をつかう
すなわちthis("ダミー");
と記すタイプ
◎this(引数)という記述で、同一クラスの別のコンストラクタを呼び出させる
おわかりかな?
やっとわかった。
(b)とか(c)とかのthisさんは、
thisのあとが、引数3つだから、
それにあった多重のオーバーロード設定で、「ああ、thisというからにはClericというコンストラクタさんが他にもあるんですね? ここもClericですけど。ほうほう、それで引数3つバージョンがあるんですね? それにこれらの引数を渡すんですね? ほうほう。了解」ということをしているんですよ
おしい、まだ違う↓
Cleric(String name,int hp){//(b)2つの引数があるクレリック
this(name, hp, MAX_MP);//(a)をこの引数で呼び出せ
}
正解はこちら
Cleric(String name,int hp){//(b)2つの引数があるクレリック
this(name, hp, Cleric.MAX_MP);//(a)をこの引数で呼び出せ
}
Cleric.MAX_HPになるんですね。
これ(c)の引数が2こだけで済むのも分かる?
(c)は(b)を呼び出し、(b)は(a)を呼び出しているという3つのコンストラクタを渡っているのだ(確認済み)
なぜこんな記述をしたか?
ひたすら重複を避けたらこういう記述になったんだろう
カプセル化:
プライベートは自分のクラスの中からだけ参照できるよという意味
何も書かなかったら同じパッケージにいるクラスからだったらOKですよ
パブリックは「どっからでも使えるよ」
--->Cleric.java
import java.util.Random;
public class Cleric {
String name;
int hp;
int mp;
static final int MAX_HP = 50;//static(max値は全員同じ)でfinalでint
static final int MAX_MP = 10;
Cleric(String name,int hp,int mp){//(a)3つの引数があるクレリック
this.name = name;
this.hp = hp;
this.mp = mp;
}
Cleric(String name,int hp){//(b)2つの引数があるクレリック
this(name, hp, Cleric.MAX_MP);//(a)をこの引数で呼び出せ
}
Cleric(String name){//(c)1つの引数があるクレリック
this(name, Cleric.MAX_HP);//(b)をこの引数で呼び出せ
}
/*
Cleric(){
this("ダミー");
}
*/
public void selfAid() {
//if文が要るのでは
this.mp -= 5;
this.hp = this.MAX_HP;
System.out.println(this.name+"はセルフエイドを使ったのでMP-5,HPが全回復");
}
public int pray(int sec) {
System.out.println(this.name+"は"+sec+"祈ったので");
//論理上の回復量
int kaihuku = new Random().nextInt(3)+sec;
//実際の回復
int kaihukuReal = Math.min(this.MAX_MP-this.mp, kaihuku);//引数に指定した2つの値のうち、どちらか小さい方の値を取得
this.mp+=kaihukuReal;
System.out.println("MPが"+kaihukuReal+"回復した");
return kaihukuReal;
}
}