この内容は具体的なコード例や文法を覚えるというものではないため、概念を理解することが重要なチャプター。ただ覚えておくべき点としてはより抽象的なスーパークラスはそのサブクラスを兼ねることができるという点。設計やコードの組み方に悩んだときに見返すとよさそう。
定義
polymorphism(ポリモーフィズム)とも呼ばれる。
1つのメッセージでオブジェクトそれぞれに応じた動きをすること。1つのメッセージを送って、相手のメソッドを実行すること。
メリット
- コードの重複を減らせる
- 将来的な修正の量を減らせる
例として、以下のコードは各インスタンスが同じフィールドを持ち、そのフィールドに同じ処理を行うコードであるが、同じ処理であるのに各変数のフィールドに個別に処理を記述してあり、将来的に修正があれば多くの箇所を修正しなければならない。
public class Main {
public static void main(String[] args) {
Hero h1 = new Hero();
Hero h2 = new Hero();
Thief t1 = new Thief();
Wizard w1 = new Wizard();
Wizard w2 = new Wizard();
// 各インスタンスの同じフィールドに50を足していく
h1.hp += 50;
h2.hp += 50;
t1.hp += 50;
w1.hp += 50;
w2.hp += 50;
}
}
この問題に多態性の概念を入れ、配列と組み合わせて修正した結果が以下のコードとなる。
public class Main {
public static void main(String[] args) {
Character[] c = new Character[5];
c[0] = new Hero();
c[1] = new Hero();
c[2] = new Thief();
c[3] = new Wizard();
c[4] = new Wizard();
for (Character ch : c) {
ch.hp += 50; // 重複していたコードを1行にまとめられた
}
}
}
コードにあるようにスーパークラス(ここで言えばCharacter)の参照型変数にサブクラス(ここで言えばHero, Thief, Wizard)のオブジェクトを代入することは可能である。ここで冒頭に述べたより抽象的なスーパークラスはそのサブクラスを兼ねることができるという点が活かされている。
他にも以下のようなコードで、同じ指示(for文内のrun()メソッド)から異なる動作(各クラスでそれぞれ定義したrun()メソッド)をさせることも可能。
public class Main {
public static void main(String[] args) {
Monster[] monsters = new Monster[3];
monsters[0] = new Slime();
monsters[1] = new Goblin();
monsters[2] = new DeathBat();
for (Monster m : monsters) {
m.run();
}
}
}