BLOG

【プログラマー 研修 Java】キャイダの記録6

3週目に突入したと思ったらすでに4週目に突入していたキャイダです。
1週間分の「過程」がすっ飛ばされ、「結果」のみ残ってしまった感覚に陥ってます。

本日は多態性というものから復習します。というか早くjavaの復習を終わらせないとと焦ってます。

・多態性

「たたいせい」と読みます。別名ポリモーフィズム(英: Polymorphism)です。
Perfumeにありそうな曲名ですね。そんなことないですか。そうですか。
この多態性、いったいなんぞやという話ですが、簡単に言うと

「ざっくりクラス扱うわ」

というものです。そうです。ざっくりです。
一々田中クラスやら山田クラスやら鈴木クラスやらに別々に処理を施すのがめんどくさいので

「お前ら人間!人間は、全員こうやって処理するぞ!!!」

みたいな感じで、とりあえずざっくり処理しちゃいたいときに多態性を使います。
今回は田中と鈴木を作ります。

//人間クラス
class Human{
	public int hp;
	void damage(int dam){
		this.hp -= dam;
	}
}

//田中君
class Tanaka extends Human{

}

//鈴木君
class Suzuki extends Human{

}

これで人間の田中と鈴木を作りました。
お次にこのようなプログラムを書きます。

//ガキ大将
class Taisyou{
	void attack(Human h){
		h.damage(10);
	}
}

ガキ大将です。イメージはジャイアンです。
彼はHumanを対象に攻撃します。
Humanならだれでもいいのです。
しかし田中君と鈴木君はHumanを継承してますが、別クラス。

class Tanaka extends Human{
	void yoyu(){
		System.out.print("ぼくたち Humanじゃないから 安心安全!");
	}
}

僕たちなら大丈夫だろうと余裕の表情を見せつけます。
ではここで、以下のコードを書いてみましょう。

public class Sayonara {
	public static void main(String[] args) {
		Human tanaka = new Tanaka();
		Human suzuki = new Suzuki();
	}
}

Humanの型に田中と鈴木を入れようとしたら、入っちゃいました。
見てくれはHumanなので、ガキ大将の攻撃メソッドの引数として十分機能します。
そう、これが多態性。

「田中って、まあ言っちゃえば人間だよね」
「鈴木も、まあ人間だよね」

このように捉えられます。
つまり言っちゃえば、継承されたクラスは、ざっくり言えば継承元だし、継承元って呼んでもいいよね。伝わるよね的な感じです。
キャイダって、まぁ人間だよね。
人間って、まぁ動物だよね。
動物って、まぁ生物だよね。
という感じです。
クラスでもこういうことが出来ちゃいます。これをすると何がいいかというと、
同じ継承元ならまとめて処理できちゃうことなんですね。
ちなみにこの「田中って人間」の理論を

is aの関係

といいます。〇〇は〇〇

ちなみに、Humanクラスとして存在する場合、見てくれはHumanなので田中独自のメソッドがあった場合は使えません。
しかしオーバーライドされたメソッドは田中のメソッドが働きます。

田中は人間である
Human tanaka = new Tanaka();
のようなis a の関係であるキャストをアップキャストといい、

人間型の田中、tanaを作り
Human tana = new Tanaka();
tanaを田中に変換する
Tanaka tanaka = (Tanaka)tana;
のようなキャストをダウンキャストといいます。

ダウンキャストは人間は田中であるとは限らない、田中ではない場合もあるので

if(変数 instanceof 型){
ダウンキャストする処理;
}

という instanceof を使い、田中は田中で合ってるのか…?という判定を行えます。

if(tana instanceof Tanaka){ 
Tanaka tanaka = (Tanaka)tana;
}

という風に使います。
そして、Taisyouのメソッドを以下のように使ってみましょう。

class Taisyou{ 
  void attack(Human h){ 
  h.damage(10);
 }
}

class Tanaka extends Human{ 
}

public class Main { 
  public static void main(String[] args){
    Human tanaka = new Tanaka();
    Taisyou tai  = new Taisyou();

    tai.attack(tanaka);//ここで大将が攻撃
    
 }
}

こうすることで大将は無事、人間の田中に攻撃が出来たと。

では前回の強田と弱田をさっくり戦わせていきましょう。
ここまでで2000文字ぐらい使っててそろそろしんどくなってきました。
ダラダラと書き過ぎました。

//強田クラス 
class Tsuyoda extends Human implements Battle{ 
  Tsuyoda(int hp , int attack){ 
    super(hp , attack);  
  }

  public void attack(Human h){ 
    System.out.println("無慈悲に振り下ろされる強田の鉄槌!"); 
    h.hp -= this.attack;
  } 

  public void cry(){ 
    System.out.println("強田は悔しく、涙を流した"); 
  } 
} 

//弱田クラス 
class Yowada extends Human implements Battle{ 
  Yowada(int hp , int attack){ 
    super(hp , attack); 
  }

  public void attack(Human h){ 
    System.out.println("弱田のまるで、赤子のような貧弱パンチ!!"); 
    h.hp -= this.attack;
  } 

  public void cry(){
    System.out.println("彼は泣いた。自分の弱さに対して…。"); 
  } 

}

これが二人のクラス。
これを使って最後にメインで戦わせます。

public class Main {
  public static void main(String[] args) {
    Human tsuyo = new Tsuyoda(100,60);
    Human  yowa = new Yowada (30,2);

    while(true){
      tsuyo.attack(yowa);
      if(yowa.hp < 1){
        yowa.cry();
        break;
      }

      yowa.attack(tsuyo);
      if(tsuyo.hp < 1){
        tsuyo.cry(); 
        break; 
      }
    }
  }
}

少し長いですが、こうすることでお互いに殴り、hpがなくなった時点でbreakでwhile文を抜けることができます。
結果は強田の勝ちです。

かなり長くなってきたので今回はこれで終わりにします。ありがどうございました。
次回はコレクション、例外を風のように駆け抜けて振り返ります。

BLOGトップへ戻る