動的バインディングと静的バインディングについて本当に混乱しています。コンパイル時にオブジェクトのタイプを決定することを静的バインディングと呼び、実行時にオブジェクトを決定することを動的バインディングと呼びます。
以下のコードで何が起こるか:
静的バインディングまたは動的バインディング?
これはどのような多型を示していますか?
class Animal
{
void eat()
{
System.out.println("Animal is eating");
}
}
class Dog extends Animal
{
void eat()
{
System.out.println("Dog is eating");
}
}
public static void main(String args[])
{
Animal a=new Animal();
a.eat();
}
実行時にa
のタイプが決定され、適切なメソッドが呼び出されるため、例は動的バインディングです。
ここで、次の2つの方法もあると仮定します。
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
main
を変更しても
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
これはAnimal is eating
。これは、callEat
の呼び出しが静的バインディングを使用し、コンパイラがa
がAnimal
型であることのみを知っているためです。
これは実際にオーバーロードとオーバーライドに依存します。このようなことをした場合:
public class Animal{}
public class Dog extends Animal{}
public class AnimalActivity{
public void eat(Animal a){
System.out.println("Animal is eating");
}
public void eat(Dog d){
System.out.println("Dog is eating");
}
}
次にメインクラスで:
public static void main(String args[])
{
Animal a=new Animal();
Animal d=new Dog();
AnimalActivity aa=new AnimalActivity();
aa.eat(a);
aa.eat(d);
}
2つの場合の結果は次のようになります。Animal is eating
しかし、それをいくつかねじってみましょう、これを持ってみましょう:
public class Animal{
public void eat(){
System.out.println("Animal is eating");
}
}
その後:
public class Dog extends Animal{
public void eat(){
System.out.println("Dog is eating");
}
}
次にメインクラスで:
public static void main(String args[]){
Animal d=new Dog();
Animal a=new Animal();
a.eat();
d.eat();
}
結果は次のようになります。
Animal is eating
Dog is eating
これは、コンパイル時にオーバーロードを「静的バインディング」にバインドし、実行時に「動的バインディング」をオーバーライドするためです。
現在のコードは_Animal is eating
_を出力します
ただし、メインクラスでDog
型のオブジェクトを作成し、Animal
に割り当てた場合、出力は動的バインディングのため_Dog is eating
_になります。
_public static void main(String args[])
{
Animal a = new Dog(); // An object of Dog is assigned to Animal
a.eat(); // Dynamically determines which eat() method to call
}
_
a
がAnimal
として宣言されていても、Dog
型のオブジェクトを指している。そのため、実行時にオブジェクトタイプが決定され、適切なeat()
メソッドが呼び出されます。
それを考える1つの方法は、_method overloading
_が静的にバインドされ、_method overriding
_が動的にバインドされていることです。
非静的関数の場合、関数が非仮想である場合は常に静的バインディングを使用します。つまり、final
キーワードが適用されているか、関数がprivate
であるか、またはその両方です。 final
は、関数を変更できないことを意味し、private
キーワードは、クラススコープのみを持つことを意味します。それ以外の場合、動的バインディングが使用されます。
静的関数の場合、静的バインディングが常に使用されます。タイプA
が渡されると、A
が参照する場所に関係なく、A
のメソッドが実行されます。
この従業員クラスに抽象earning()
関数があり、各クラスに異なるtoString()
実装があることを確認してください
Employee[] employees = new Employee[4];
// initialize array with Employees
employees[0] = new SalariedEmployee();
employees[1] = new HourlyEmployee();
employees[2] = new CommissionEmployee();
employees[3] = new BasePlusCommissionEmployee();
for (Employee currentEmployee : employees){
System.out.println(currentEmployee); // invokes toString
System.out.printf("earned $%,.2f%n", currentEmployee.earnings());
}
メソッドtoString
およびearnings
へのすべての呼び出しは、currentEmployeeが参照するexecution time
に基づいて、type of the object
で解決されます。
このプロセスはdynamic binding
またはlate binding
として知られています
事例1:
Animal a =new Animal();
a.eat();
ケース2:
Animal a=new Dog();
a.eat();
どちらも動的バインドです。コンパイル時にオブジェクトのタイプが決定されますが、実行時にインスタンスに基づいて、対応するeatメソッドが割り当てられたオブジェクトがJVMによって動的にバインドされるためです。
前者の場合、動物クラスのeatメソッドが呼び出されますが、後者の場合、AnimalオブジェクトにDogインスタンスが割り当てられると、dogクラスのeatが呼び出されます。Dogのインスタンスも動物のインスタンスです。つまり、「is a」関係であると見なすことができます。ここで、オブジェクトのタイプは、実行時およびJVMで犬として決定されます。 dogクラスのeatメソッドを動的にバインドします。
このリンクもチェックしてください
http://www.javatpoint.com/static-binding-and-dynamic-binding
http://www.coderanch.com/t/386124/Java/java/Static-Binding-Dynamic-Binding