Javaで、instanceof ってあるあるだよね~、からの、使い方を誤っていました...
そんな反省の意味を込めて、今日もJava を。
そして、なんだかんだで、Javaに関する記事が99回目になりました。毎回、どうしようもない記事ばかりが多くなっているのですが、読んでくださっている皆様ありがとうございます。次回が100回目なんだけども、少しはまともな記事を書きたい...どうもボクです。
というわけで、レッツ~トライ。
スーパークラスに詰め込んで~
「ナイフ ランプ鞄に 詰め込んで 父さんが残した 熱い想い母さんがくれた あのまなざし.」 という、『天空の城ラピュタ』の「君をのせて」の歌詞が出たところで、スーパークラスに詰め込もうじゃないですか、サブクラスたちを。
というわけで、Eclipseを起動し、Javaプロジェクトを作成し、適当なクラスを作成。
ソースはこんな感じ。フィールドとかコンストラクタとか超適当なクラス構成です。
package dto; public class SuperMan { private String name; private String from; public SuperMan() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } }
Sub.java ← サブクラス
package dto; public class Sub extends SuperMan { private String hobby; private int power; public Sub() { super(); } public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } public int getPower() { return power; } public void setPower(int power) { this.power = power; } }
IppMan.java ← サブクラス
package dto; public class IppMan extends SuperMan { private String syonento; private String jinkyo; private String Hyoshi; private int power; public IppMan() { super(); } public String getSyonento() { return syonento; } public void setSyonento(String syonento) { this.syonento = syonento; } public String getJinkyo() { return jinkyo; } public void setJinkyo(String jinkyo) { this.jinkyo = jinkyo; } public String getHyoshi() { return Hyoshi; } public void setHyoshi(String hyoshi) { Hyoshi = hyoshi; } public int getPower() { return power; } public void setPower(int power) { this.power = power; } }
ErrorMan.java ← サブクラス
package dto; public class ErrorMan extends SuperMan { private String miss; private int power; public ErrorMan() { super(); } public String getMiss() { return miss; } public void setMiss(String miss) { this.miss = miss; } public int getPower() { return power; } public void setPower(int power) { this.power = power; } }
TestSubInToSupser.java ← 実行クラス
package main; import dto.ErrorMan; import dto.IppMan; import dto.Sub; import dto.SuperMan; public class TestSubInToSupser { private static int SUPERMAN_BORDERLINE = 100; private static int STARMAN_BORDERLINE = 60; public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ int power = (int)(Math.random() * 100) +1; int chance = (int)(Math.random() * 10) +1; SuperMan sp = null; if (chance == 10) { sp = takeIppManOrErrorMan(sp, power); } else { sp = takeSubManOrErrorMan(sp, power); } if (sp instanceof IppMan) { System.out.println("イップマン"); } else if (sp instanceof Sub) { System.out.println("一般の人"); } else if (sp instanceof ErrorMan) { System.out.println("エラーマンが..."); } } public static SuperMan takeIppManOrErrorMan(SuperMan sp, int power) { if (STARMAN_BORDERLINE < power && power <= SUPERMAN_BORDERLINE) { sp = new IppMan(); } else { sp = new ErrorMan(); } return sp; } public static SuperMan takeSubManOrErrorMan(SuperMan sp, int power) { if (0 < power && power < STARMAN_BORDERLINE ) { sp = new Sub(); } else { sp = new ErrorMan(); } return sp; } }
んで、実行。
1回目の実行で出た。
3回ぐらい実行して出た。
20回ぐらい実行して出た。
スーパクラスに、スーパクラスを継承したサブクラスたちを入れとくことができると。
そして、そのスーパークラスを instanceof すると、サブクラスたちを判定できるんだと。ポリモーフィズムっちゅうやつですかね。
一回しか実行したくないメソッドの戻り値の型が、複数ある場合でも、戻り値の型が共通のスーパークラスを継承していてくれれば、メソッドの戻り値を受け取る変数として共通のスーパークラスで受け取れるということですね、つまり、メソッドの実行が1回で済むと。あくまで、そういう設計になってるクラスの場合に限りますが。
■ 今日の教訓
共通のスーパークラスを継承したサブクラスが用意されている場合は、共通のスーパークラスの変数で受け取れる。その後で、instanceof して、どのサブクラスを受け取れたか確認すればOK。
何にせよ、昨日よりは1mmぐらい成長したと思い込んでみますか...。
今回はこのへんで。