コンパイル時ポリモーフィズムと実行時ポリモーフィズムの違いを徹底解説
ポリモーフィズム(多態性)とは
ポリモーフィズムは、オブジェクト指向プログラミング(OOP)における最も重要な概念の一つです。「同じメソッド呼び出しに対して、状況に応じて異なる振る舞いを実現できる」という性質を指し、単一のタスクを複数の方法で処理することを可能にします。
Javaなどのオブジェクト指向言語では、ポリモーフィズムは主に次の2種類に分類されます。
- コンパイル時ポリモーフィズム(静的ポリモーフィズム) … 代表例はメソッドのオーバーロード
- 実行時ポリモーフィズム(動的ポリモーフィズム) … 代表例はメソッドのオーバーライド
両者の違いを比較表で確認
まずは、コンパイル時ポリモーフィズムと実行時ポリモーフィズムの主な違いを表に整理しました。
| No. | 比較項目 | コンパイル時ポリモーフィズム | 実行時ポリモーフィズム |
|---|---|---|---|
| 1 | 基本 | メソッド呼び出しと実装の結び付け(バインディング)がコンパイル時に行われる | どのメソッドが呼び出されるかが実行時に決定される |
| 2 | 静的/動的バインディング | 静的バインディング(早期バインディング)によって実現 | 動的バインディング(遅延バインディング)によって実現 |
| 3 | 継承 | 継承は不要 | 継承(またはインターフェースの実装)が前提となる |
| 4 | 代表例 | メソッドのオーバーロード | メソッドのオーバーライド |
| 5 | 実現方法 | 同じクラス内に、同名でも引数の型・個数が異なるメソッドを複数定義する | サブクラスで親クラスのメソッドを同じシグネチャで再定義する |
コンパイル時ポリモーフィズムのコード例(オーバーロード)
次の例では、display() メソッドを引数なしと引数ありの2通りで定義しています。どちらが呼び出されるかは、引数の構成からコンパイルの時点で確定します。
public class Main {
public static void main(String args[]) {
Sample obj = new Sample();
obj.display(); // 引数なしのメソッドが呼ばれる
obj.display("Polymorphism"); // 引数ありのメソッドが呼ばれる
}
}
class Sample {
void display() {
System.out.println("引数なしのdisplayメソッド");
}
void display(String value) {
System.out.println("引数ありのdisplayメソッド: " + value);
}
}実行結果:
引数なしのdisplayメソッド
引数ありのdisplayメソッド: Polymorphismこのように、同じ名前のメソッドでも引数リストが異なれば別のメソッドとして扱われるのがオーバーロードです。
実行時ポリモーフィズムのコード例(オーバーライド)
次の例では、親クラス型の変数に子クラスのインスタンスを代入しています。obj.display() の呼び出し先は、実際に代入されているオブジェクトの種類に基づいて実行時に決まります。
public class Main {
public static void main(String args[]) {
// 親クラス型の変数に子クラスのインスタンスを代入
Parent obj = new Child();
obj.display(); // 実行時にChildのdisplay()が呼び出される
}
}
class Parent {
public void display() {
System.out.println("親クラスのメソッド");
}
}
class Child extends Parent {
@Override
public void display() {
System.out.println("子クラスでオーバーライドしたメソッド");
}
}実行結果:
子クラスでオーバーライドしたメソッド変数の宣言は親クラス型ですが、実際に生成されているのは子クラスのインスタンスのため、実行時には子クラス側で上書き(オーバーライド)されたメソッドが優先的に呼び出されます。これが動的バインディングによる実行時ポリモーフィズムです。
まとめ
- コンパイル時ポリモーフィズムは、メソッドの選択がコンパイル時に確定する静的な仕組みで、同一クラス内のオーバーロードが代表例。継承は不要。
- 実行時ポリモーフィズムは、実際に呼び出されるメソッドが実行時に決まる動的な仕組みで、継承関係でのオーバーライドが代表例。
両者を正しく理解して使い分けることで、柔軟で拡張性の高いオブジェクト指向設計を実現できます。特に実行時ポリモーフィズムは、共通インターフェースを利用した疎結合なコード設計の土台となる重要な概念なので、しっかり押さえておきましょう。
-
JavaのIteratorとEnumerationの違いを徹底比較!使い分けのポイントを解説
はじめに:IteratorとEnumerationとはJavaのコレクションフレームワークには、コレクション内の要素を順番に走査(トラバース)しながらアクセスするための仕組みとして「カーソル」が用意されています。その代表格が Iterator(イテレータ) と Enumeration(列挙) の2つです。両者はどちらもコレクションフレームワークに属しますが、登場した時期と役割が異なります。EnumerationはJDK 1.0から存在する歴史あるインターフェースで、IteratorはJDK 1.2でコレクションフレームワークとともに導入された、より新しいインターフェースです。Enumerati
-
JavaでのArrayListとHashSetの違いを徹底解説!使い分けのポイントも紹介
HashSetとArrayListは、どちらもJavaコレクションフレームワークにおいて最も重要なクラスの一つです。それぞれ特徴が異なるため、用途に応じた適切な使い分けが求められます。本記事では、ArrayListとHashSetの主な違いを6つの観点から比較し、実際のサンプルコードとともにわかりやすく解説します。ArrayListとHashSetの違い一覧No.項目ArrayListHashSet1実装インターフェースListインターフェースを実装しています。Setインターフェースを実装しています。2内部構造内部的には配列(動的配列)を使って実装されています。内部的にはHashMapを使って