Статическое связывание и динамическое связывание

Я действительно смущен динамической привязкой и статической привязкой. Я читал, что определение типа объекта во время компиляции называется статической привязкой, а определение его во время выполнения-динамической привязкой.

что происходит в код ниже:

статическая привязка или динамическая привязка?
Что это за полиморфизм?

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

6 ответов


ваш пример динамическое связывание, потому что во время выполнения определяется, что типа a is, и вызывается соответствующий метод.

теперь предположим, что у вас есть следующие два метода:

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 to

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);
}

результат в обоих случаях будет: 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() метод называется.

один из способов думать об этом, method overloading is статически связанный и method overriding динамически связаны.


для нестатических функций вы используете статическую привязку, когда функция не является виртуальной, т. е. final ключевое слово применяется к нему и/или функция private. final подразумевает, что функция не может быть изменен и private сайта подразумевает только рамками класса. В противном случае используется динамическая привязка.

для статических функций всегда используется статическая привязка. Если тип A передается, он будет работать Aметод, независимо от того, где A ссылки.


Пример 1:

Animal a =new Animal();
a.eat();

Пример 2:

Animal a=new Dog(); 
a.eat();

здесь оба являются динамической привязкой, потому что во время компиляции тип объекта определяется, но во время выполнения на основе экземпляра объект, которому назначен соответствующий метод eat, будет динамически привязываться JVM .

в первом случае вызывается метод animal class eat, тогда как во втором классе dog eat вызывается как объект Animal присваивается экземпляру Dog.Пример собаки также является примером животного. То есть вы можете принять это как "это" отношение собака-это животное.Таким образом, тип объекта определяется как dog во время выполнения, а JVM динамически связывает метод eat класса dog.

проверьте это ссылки тоже

http://www.javatpoint.com/static-binding-and-dynamic-binding

http://www.coderanch.com/t/386124/java/java/Static-Binding-Dynamic-Binding


проверить это класс employee имеет аннотация earning() функция и каждый класс имеет deferent 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 решаются на execution time, на основании type of the object к которому currentEmployee относится,

этот процесс известен как dynamic binding или late binding

ссылки: На Java Как Программировать (Ранние Объекты), Десятое Издание