Java での静的バインディングと動的バインディングの違い
このチュートリアルでは、Java の静的バインディングと動的バインディングの違いを紹介し、このトピックをガイドするためのサンプルコードをいくつか示します。
バインディングとは、メソッド呼び出しをメソッド実装にリンクすることであり、静的と動的の 2つのタイプがあります。ポリモーフィズムによれば、オブジェクトには多くの形式があり、これらの形式はコンパイル時または実行時に解決できます。
静的バインディングは、メソッド呼び出しがコンパイル時にメソッド実装にリンクされている場合に発生します。動的バインディングは、実行時にバインディングが行われるときに発生します。これらの 2 種類のバインディングについて詳しく学び、いくつかの例を見てみましょう。
Java での静的バインディング
上で説明したように、静的バインディングはコンパイル時に発生するバインディングです。コンパイル時に発生するため、早期バインディングとも呼ばれます。
静的バインディングの場合、コンパイラーは、使用するメソッドの実装を正確に認識しています。バインディングにタイプまたはクラス情報を使用します。メソッドのオーバーロードは静的バインディングの例です。
子クラスは static、final、および private メソッドをオーバーライドできないため、すべての static、final、および private メソッドは静的バインディングを使用することに注意してください。コンパイラは、コンパイル時にどのメソッド実装を使用するかを認識しています。コンパイラは、親クラスのメソッドをオーバーライドできないことを認識しているため、常にメソッドの親クラスの実装を使用します。
さらに、静的バインディングは、関連するオーバーヘッドが少ないため、パフォーマンスも向上します。
Java での静的バインディングの例
以下のコードでは、学校のクラスに静的な ringBell()
メソッドがあり、このクラスは Classroom
によって拡張されています。Classroom
には ringBell()
メソッドもあります。
ringBell()
メソッドは静的であるため、コンパイラはクラスタイプをチェックするだけで、割り当てられたオブジェクトクラスを考慮しません。したがって、School
クラスを使用して Classroom(School s2 = new Classroom())
のオブジェクトを作成する場合、Classroom
クラスではなく School
クラスの実装が考慮されます。
class School {
public static void ringBell() {
System.out.println("Ringing the school bell...");
}
}
class Classroom extends School {
public static void ringBell() {
System.out.println("Ringing the classroom bell...");
}
}
public class Main {
public static void main(String[] args) {
School s1 = new School(); // Type is School
s1.ringBell();
Classroom c1 = new Classroom(); // Type is Classroom
c1.ringBell();
School s2 = new Classroom(); // Type is School
s2.ringBell();
}
}
出力:
Ringing the school bell...
Ringing the classroom bell...
Ringing the school bell...
Java での動的バインディング
コンパイラはコンパイル時に使用する実装を認識していないため、動的バインディングは実行時にバインディングを解決します。
バインディングは、コンパイル時ではなく実行時の後の段階で解決されるため、遅延バインディングとも呼ばれます。動的バインディングは、タイプやクラスではなく、バインディングにオブジェクトも使用します。メソッドのオーバーライドは、動的バインディングの例です。
Java での動的バインディングの例
以下のコードでは、ringBell()
メソッドは静的ではないため、オーバーライドが発生します。コンパイラは、ringBell()
メソッドのどの実装を使用する必要があるかを認識していないため、バインディングは実行時に解決されます。
実行時に、オブジェクトは、それを作成するために使用されたタイプではなく、考慮されます。したがって、School
クラスを使用して Classroom
のオブジェクトを作成する場合、School
クラスではなく、Classroom
クラスの実装が考慮されます。
class School {
public void ringBell() {
System.out.println("Ringing the school bell...");
}
}
class Classroom extends School {
@Override
public void ringBell() {
System.out.println("Ringing the classroom bell...");
}
}
public class Main {
public static void main(String[] args) {
School s1 = new School(); // Type is School and object is of School
s1.ringBell();
Classroom c1 = new Classroom(); // Type is Classroom and object is of Classroom
c1.ringBell();
School s2 = new Classroom(); // Type is School and object is of Classroom
s2.ringBell();
}
}
出力:
Ringing the school bell...
Ringing the classroom bell...
Ringing the classroom bell...
Java での静的バインディングと動的バインディング
静的バインディングは、コンパイル時にメソッド呼び出しをメソッド実装に接続することです。一方、動的バインディングは、実行時にメソッド呼び出しをメソッド実装に接続することです。
ポリモーフィズムの概念を理解するには、これらの手法の両方を知ることが重要です。静的バインディングは、static、final、および private メソッドで使用されます。このバインディングは、メソッドがオーバーロードされた場合に機能します。動的バインディングは、仮想メソッド(Java ではデフォルトで仮想)に使用され、オーバーライドされたメソッドをバインドするために使用されます。