web-dev-qa-db-ja.com

静的バインディングと動的バインディング

動的バインディングと静的バインディングについて本当に混乱しています。コンパイル時にオブジェクトのタイプを決定することを静的バインディングと呼び、実行時にオブジェクトを決定することを動的バインディングと呼びます。

以下のコードで何が起こるか:

静的バインディングまたは動的バインディング?
これはどのような多型を示していますか?

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();
}
30
Abhinav

実行時に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の呼び出しが静的バインディングを使用し、コンパイラがaAnimal型であることのみを知っているためです。

67

これは実際にオーバーロードオーバーライドに依存します。このようなことをした場合:

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

これは、コンパイル時にオーバーロードを「静的バインディング」にバインドし、実行時に「動的バインディング」をオーバーライドするためです。

22
Muhammad Ramahy

現在のコードは_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
}
_

aAnimalとして宣言されていても、Dog型のオブジェクトを指している。そのため、実行時にオブジェクトタイプが決定され、適切なeat()メソッドが呼び出されます。

それを考える1つの方法は、_method overloading_が静的にバインドされ、_method overriding_が動的にバインドされていることです。

1
srikfreak

非静的関数の場合、関数が非仮想である場合は常に静的バインディングを使用します。つまり、finalキーワードが適用されているか、関数がprivateであるか、またはその両方です。 finalは、関数を変更できないことを意味し、privateキーワードは、クラススコープのみを持つことを意味します。それ以外の場合、動的バインディングが使用されます。

静的関数の場合、静的バインディングが常に使用されます。タイプAが渡されると、Aが参照する場所に関係なく、Aのメソッドが実行されます。

1
Don Larynx

この従業員クラスに抽象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として知られています

参照: Java™How To Program(初期オブジェクト)、第10版

0

事例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

0
Lakshmi