1. 導入:なぜPolymorphismが重要なのか
Javaを学習していると必ず耳にする「Polymorphism(ポリモーフィズム/多態性)」。一言で言えば、「同じメッセージ(メソッド呼び出し)を送っても、オブジェクトによって異なる動作をすること」です。
これがなぜ重要かというと、将来的に機能を追加したり修正したりする際、既存のコードを壊さずに柔軟に対応できるからです。初心者の方がこの概念を理解すると、if文だらけの読みづらいコードから卒業し、プロらしい「拡張性の高いコード」が書けるようになります。
2. 基礎知識:ポリモーフィズムの仕組み
ポリモーフィズムを実現するために欠かせないのが「継承」と「インターフェース」です。
・継承(Inheritance): 親クラスの機能を子クラスが引き継ぐこと。
・インターフェース(Interface): クラスが「何ができるか」という能力を定義したもの。
・default methods: インターフェースに追加された機能で、実装クラスで書き換えなくてもデフォルトの動作を持たせることができます。
・private interface methods: インターフェース内部だけで使う処理を定義し、コードの重複を防ぎます。
これらを使うことで、呼び出し側は「具体的な中身」を気にせず、インターフェースの型だけを意識してコードを書くことができます。
3. 実装:ポリモーフィズムの具体例
例えば、「動物」というインターフェースを作り、犬や猫がそれぞれ「鳴く」という動作を実装する場合を考えます。呼び出し側は、相手が犬か猫かを判断することなく、ただ「鳴け!」と命令するだけで済みます。
4. サンプルプログラム
以下のコードをコピーして、IDEやテキストエディタで動作を確認してみてください。
// インターフェースの定義
interface Animal {
// 抽象メソッド(実装クラスで必ず実装が必要)
void sound();
// defaultメソッド(実装クラスで書き換え可能)
default void sleep() {
System.out.println(“Zzz…(デフォルトの睡眠処理)”);
}
// privateメソッド(インターフェース内部の共通処理用)
private void logAction(String action) {
System.out.println(“[ログ] 動物が実行中: ” + action);
}
// privateメソッドを呼ぶためのdefaultメソッド
default void performAction(String action) {
logAction(action);
}
}
// 犬クラス
class Dog implements Animal {
@Override
public void sound() {
System.out.println(“ワンワン!”);
}
}
// 猫クラス
class Cat implements Animal {
@Override
public void sound() {
System.out.println(“ニャー!”);
}
}
public class Main {
public static void main(String[] args) {
// ポリモーフィズムの活用: Animal型として扱う
Animal[] animals = {new Dog(), new Cat()};
for (Animal a : animals) {
a.performAction(“鳴く”);
a.sound(); // ここでそれぞれのクラスの動作が呼び出される
a.sleep();
System.out.println(“—“);
}
}
}
5. 応用・注意点:現場で役立つアドバイス
現場でよくある失敗は、インターフェースを過剰に細分化しすぎることです。何でもかんでもインターフェースにすると、コードの追いかけが非常に困難になります。
また、「継承よりもインターフェースを使う」のがJavaの現代的な設計思想です。クラス継承は「is-a関係(犬は動物である)」が明確な場合のみ使用し、機能の追加や振る舞いの定義にはインターフェースを活用しましょう。この使い分けができるようになると、あなたの書くJavaコードの品質は格段に上がります!

コメント