Статическая и динамическая привязка в Java


в настоящее время я выполняю задание для одного из моих классов, и в нем я должен привести примеры, используя синтаксис Java, из статический и динамическое связывание.

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

Я нашел пример статической привязки в интернете, который дает этот пример:

public static void callEat(Animal animal) {
    System.out.println("Animal is eating");
}

public static void callEat(Dog dog) {
    System.out.println("Dog is eating");
}

public static void main(String args[])
{
    Animal a = new Dog();
    callEat(a);
}

и что это будет печатать "животное ест", потому что вызов callEat использует статическое связывание, но я не уверен, что почему это считается статической привязкой.

до сих пор ни один из источников, которые я видел, не смог объяснить это таким образом, что я могу следовать.

6 59

6 ответов:

С Javarevisited сообщение в блоге:

вот несколько важных различий между статической и динамической привязкой:

  1. статическая привязка в Java происходит во время компиляции, а динамическая привязка происходит во время выполнения.
  2. private,final и static методы и переменные используют статическую привязку и связаны компилятором, в то время как виртуальные методы связаны во время выполнения на основе объекта времени выполнения.
  3. статическая привязка использует Type (class в Java) информация для привязки, в то время как динамическая привязка использует объект для разрешения привязки.
  4. перегруженные методы связаны с использованием статической привязки, а переопределенные методы связаны с использованием динамической привязки во время выполнения.

вот пример, который поможет вам понять как статическое, так и динамическое связывание в Java.

пример статической привязки в Java

public class StaticBindingTest {  
    public static void main(String args[]) {
        Collection c = new HashSet();
        StaticBindingTest et = new StaticBindingTest();
        et.sort(c);
    }
    //overloaded method takes Collection argument
    public Collection sort(Collection c) {
        System.out.println("Inside Collection sort method");
        return c;
    }
    //another overloaded method which takes HashSet argument which is sub class
    public Collection sort(HashSet hs) {
        System.out.println("Inside HashSet sort method");
        return hs;
    }
}

выход: метод сортировки внутри коллекции

пример динамической привязки в Java

public class DynamicBindingTest {   
    public static void main(String args[]) {
        Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
        vehicle.start(); //Car's start called because start() is overridden method
    }
}

class Vehicle {
    public void start() {
        System.out.println("Inside start method of Vehicle");
    }
}

class Car extends Vehicle {
    @Override
    public void start() {
        System.out.println("Inside start method of Car");
    }
}

выход: внутренний метод запуска автомобиля

подключение вызова метода к телу метода называется привязкой. Как сказал Маулик " статическая привязка использует информацию типа (класса в Java) для привязки, а динамическая привязка использует объект для разрешения привязки."Итак, этот код:

public class Animal {
    void eat() {
        System.out.println("animal is eating...");
    }
}

class Dog extends Animal {

    public static void main(String args[]) {
        Animal a = new Dog();
        a.eat(); // prints >> dog is eating...
    }

    @Override
    void eat() {
        System.out.println("dog is eating...");
    }
}

даст результат:собака ест... потому что он использует ссылку на объект, чтобы найти, какой метод использовать. Если мы изменим приведенный выше код на этот:

class Animal {
    static void eat() {
        System.out.println("animal is eating...");
    }
}

class Dog extends Animal {

    public static void main(String args[]) {

        Animal a = new Dog();
        a.eat(); // prints >> animal is eating...

    }

    static void eat() {
        System.out.println("dog is eating...");
    }
}

Она будет производить : животное ест... поскольку это статический метод, поэтому он использует тип (в данном случае животное), чтобы решить, какой статический метод вызывать. Кроме статических методов частные и конечные методы используют тот же подход.

компилятор знает только, что тип "а"Animal; это происходит во время компиляции, из-за чего он называется статической привязкой (перегрузка метода). Но если это динамическая привязка, то он будет вызывать Dog метод класса. Вот пример динамической привязки.

public class DynamicBindingTest {

    public static void main(String args[]) {
        Animal a= new Dog(); //here Type is Animal but object will be Dog
        a.eat();       //Dog's eat called because eat() is overridden method
    }
}

class Animal {

    public void eat() {
        System.out.println("Inside eat method of Animal");
    }
}

class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("Inside eat method of Dog");
    }
}

выход: Внутри есть метод собаки

есть три основных различия между статической и динамической привязкой при проектировании компиляторов и как переменные и процедуры переданы runtime окружающая среда. Эти различия заключаются в следующем:

Статическое Связывание: в статической привязке обсуждаются три следующие проблемы:

  • определение процедуры

  • объявление a имя (переменная и др.)

  • объем декларации

Динамическое Связывание: три проблемы, которые встречаются в динамической привязке, следующие:

  • активация процедуры

  • привязка имени

  • время жизни привязки

со статическим методом в Родительском и дочернем классе: статическая привязка

public class test1 {   
    public static void main(String args[]) {
        parent pc = new child(); 
        pc.start(); 
    }
}

class parent {
    static public void start() {
        System.out.println("Inside start method of parent");
    }
}

class child extends parent {

    static public void start() {
        System.out.println("Inside start method of child");
    }
}

// Output => Inside start method of parent

Динамическое Связывание :

public class test1 {   
    public static void main(String args[]) {
        parent pc = new child();
        pc.start(); 
    }
}

class parent {
   public void start() {
        System.out.println("Inside start method of parent");
    }
}

class child extends parent {

   public void start() {
        System.out.println("Inside start method of child");
    }
}

// Output => Inside start method of child

потому что компилятор знает, что связывание во время компиляции. Например, если вы вызываете метод на интерфейсе, то компилятор не может знать, и привязка разрешена во время выполнения, потому что фактический объект, имеющий метод, вызванный на нем, может быть одним из нескольких. Поэтому это время выполнения или динамическая привязка.

ваш вызов привязан к классу Animal во время компиляции, потому что вы указали тип. Если вы передали эту переменную в другой метод где-то в противном случае никто не знал бы (кроме вас, потому что вы написали это), какой фактический класс это будет. Единственная подсказка-это объявленный тип животного.