2013-05-20 6 views
28

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

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

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

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

не должен ли ваш a.eat() находиться внутри основного метода? – Lakshmi

+0

Прочтите «Head core core java» как можно скорее. – AmitG

+2

это больше [динамическое связывание] (http://stackoverflow.com/questions/5658553/question-about-java-overloading-dynamic-binding) –

ответ

60

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

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

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.

+2

Наконец, правильный ответ! +1. –

+0

+1 для такого приятного примера .. – amicngh

+0

@Heuster Thanx для такого замечательного примера. Но может ли я сказать, какой полиморфизм выставляет мой код? статический или временный полиморфизм? – Abhinav

1

Ваш текущий код выведет 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 статически связан и method overriding динамически связан.

+0

Thanx для ответа. – Abhinav

+0

Итак, u r говорит, что мой код демонстрирует статическую привязку, обряд? – Abhinav

+1

@ пользователь2401175 нет. В ответе говорится «из-за динамического связывания». Таким образом, код показывает пример динамического связывания, потому что метод eat() выбирается во время выполнения на основе конкретного типа животного, на котором он называется (Dog), а не объявленного типа переменной (Animal) , –

0

Случай 1:

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

Случай 2:

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

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

В первом случае называется метод употребления класса животных, тогда как во втором классе собака есть, так как объекту животного назначается экземпляр собаки. Экземпляр собаки также является экземпляром животного. То есть вы можете считать, что «- это отношение». Собака - это животное. Таким образом, тип объекта определяется как собака во время выполнения, а JVM динамически связывает метод питания собаки.

Проверить это ссылки слишком

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

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

+0

Thanx, но может у меня сказать, какой тип полиморфизма мой код выставляется? Является статическим или полиморфизмом времени выполнения? – Abhinav

+1

Это просто неправильно. Это всегда JVM, во время выполнения, который выбирает, какой надменный метод должен быть вызван, на основе конкретного типа времени выполнения объекта. Является ли объект экземпляром объявленного типа или экземпляром подтипа ничего не меняет: привязка является динамической. –

+0

@ user2401175 это случай 1 это время полиморфизма времени компиляции и case2: это время выполнения проверить эту ссылку, я думаю, что он отвечает на ваш вопрос http://stackoverflow.com/q/2152848/2006839 – Lakshmi

21

Это действительно зависит от перегрузки и перекрывая если вы сделали что-то вроде этого:

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 

это потому, что перегрузка связывается в время компиляции «статическое связывание» в то время как переопределяете связывает во время выполнения «динамическое связывание»

1

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

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

0

проверка этого класса работник имеет абстрактную 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 разрешаются в execution time, на основе type of the object, к которому относится currentEmployee,

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

ссылка: Java™ How To Program (Early Objects), Tenth Edition

Смежные вопросы