Javaの静的および動的バインディング
1. 前書き
Polymorphismを使用すると、オブジェクトは複数の形式をとることができます。メソッドがポリモーフィズムを示す場合、コンパイラーはメソッドの名前を最終的な実装にマップする必要があります。
コンパイル時にマッピングされている場合は、静的または早期バインディングです。
実行時に解決される場合は、動的バインディングまたは遅延バインディングと呼ばれます。
2. コードを通して理解する
サブクラスがスーパークラスを拡張すると、サブクラスで定義されたメソッドを再実装できます。 これは、メソッドのオーバーライドと呼ばれます。
たとえば、スーパークラスAnimal:を作成しましょう
public class Animal {
static Logger logger = LoggerFactory.getLogger(Animal.class);
public void makeNoise() {
logger.info("generic animal noise");
}
public void makeNoise(Integer repetitions) {
while(repetitions != 0) {
logger.info("generic animal noise countdown " + repetitions);
repetitions -= 1;
}
}
}
そしてサブクラスDog:
public class Dog extends Animal {
static Logger logger = LoggerFactory.getLogger(Dog.class);
@Override
public void makeNoise() {
logger.info("woof woof!");
}
}
AnimalクラスのmakeNoise()のようにメソッドをオーバーロードすると、コンパイラーはコンパイル時にメソッドとそのコードを解決します。 This is an example of static binding.
ただし、タイプDogのオブジェクトをタイプAnimalの参照に割り当てると、コンパイラーは実行時に関数コードのマッピングを解決します。 これは動的バインディングです。
これがどのように機能するかを理解するために、クラスとそのメソッドを呼び出す小さなコードスニペットを書いてみましょう。
Animal animal = new Animal();
// calling methods of animal object
animal.makeNoise();
animal.makeNoise(3);
// assigning a dog object to reference of type Animal
Animal dogAnimal = new Dog();
dogAnimal.makeNoise();
The output of the above code will be:
com.example.binding.Animal - generic animal noise
com.example.binding.Animal - generic animal noise countdown 3
com.example.binding.Animal - generic animal noise countdown 2
com.example.binding.Animal - generic animal noise countdown 1
com.example.binding.Dog - woof woof!
それでは、クラスを作成しましょう。
class AnimalActivity {
public static void eat(Animal animal) {
System.out.println("Animal is eating");
}
public static void eat(Dog dog) {
System.out.println("Dog is eating");
}
}
これらの行をメインクラスに追加しましょう。
AnimalActivity.eat(dogAnimal);
出力は次のようになります。
com.example.binding.AnimalActivity - Animal is eating
This example shows that a static function undergoes static binding。
その理由は、サブクラスが静的メソッドをオーバーライドできないためです。 サブクラスが同じメソッドを実装すると、スーパークラスのメソッドが非表示になります。 Similarly, if a method is final or private, the JVM will do a static binding.
静的バインドメソッドは特定のオブジェクトに関連付けられていませんが、Type(Javaのクラス)で呼び出されます。 このようなメソッドの実行はわずかに高速です。
他のメソッドは、デフォルトでは自動的にJavaの仮想メソッドです。 JVMは実行時にそのようなメソッドを解決し、これは動的バインディングです。
正確な実装はJVMに依存しますが、Jが仮想テーブルを検索してメソッドが呼び出されるオブジェクトを決定するCのようなアプローチが必要です。
3. 結論
バインディングは、ポリモーフィズムを実装する言語の不可欠な部分です。静的バインディングと動的バインディングの両方の意味を理解して、アプリケーションが希望どおりに動作していることを確認することが重要です。
ただし、その理解により、クラスの継承とメソッドのオーバーロードを効果的に使用できます。
いつものように、コードはover on GitHubで利用できます。