Статический Vs. Динамическая привязка в Java
в настоящее время я выполняю задание для одного из моих классов, и в нем я должен привести примеры, используя синтаксис Java, из static и динамическое связывание.
Я понимаю основную концепцию, что статическая привязка происходит во время компиляции, а динамическая привязка происходит во время выполнения, но я не могу понять, как они на самом деле работают.
Я нашел пример статической привязки в интернете, который дает этот пример:
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 ответов
С Javarevisited сообщение в блоге:
вот несколько важных различий между статической и динамической привязкой:
- статическая привязка в Java происходит во время компиляции, в то время как динамическая привязка происходит во время выполнения.
private
,final
иstatic
методы и переменные используют статическую привязку и связаны компилятором, в то время как виртуальные методы связаны во время выполнения на основе объекта времени выполнения.- статическая привязка использует
Type
(class
в Java) информация для привязки, в то время как динамическая привязка использует объект для разрешения привязки.- перегруженные методы связаны с использованием статической привязки, а переопределенные методы связаны с использованием динамической привязки во время выполнения.
вот пример, который поможет вам понять как статическую, так и динамическую привязку в 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; } }
выход: внутри коллекция метода sort
пример динамической привязки в 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...");
}
}
он произведет:животное ест... поскольку это статический метод, он использует Type (в данном случае Animal) для разрешения вызова статического метода. Помимо статических методов частные и конечные методы используют один и тот же подход.
компилятор знает только, что тип "а"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");
}
}
выход: Внутри ешьте метод собаки
существует три основных различия между статической и динамической привязкой при разработке компиляторов и как переменные и процедуры переданы время работы окружающая среда. Эти различия заключаются в следующем:
Статическое Связывание: в статической привязке обсуждаются три следующие проблемы:
определение процедуры
объявление 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 во время компиляции, потому что вы указали тип. Если вы передали эту переменную в другой метод где-то иначе никто не знал бы (кроме вас, потому что вы написали это), какой фактический класс это будет. Единственный ключ к разгадке-объявленный тип животного.