Static Binding and Dynamic Binding
I am really confused about dynamic binding and static binding. I have read that determining the type of an object at compile time is called static binding and determining it at runtime is called dynamic binding.
What happens in the code below:
Static binding or dynamic binding?
What kind of polymorphism does this show?
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();
}
Your example is dynamic binding, because at run time it is determined what the type of a
is, and the appropriate method is called.
Now assume you have the following two methods as well:
public static void callEat(Animal animal) {
System.out.println("Animal is eating");
}
public static void callEat(Dog dog) {
System.out.println("Dog is eating");
}
Even if you change your main
to
public static void main(String args[])
{
Animal a = new Dog();
callEat(a);
}
this will print Animal is eating
, because the call to callEat
uses static binding, and the compiler only knows that a
is of type Animal
.
This really depends on overloading and overriding if you did something like this:
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");
}
}
then in the main class:
public static void main(String args[])
{
Animal a=new Animal();
Animal d=new Dog();
AnimalActivity aa=new AnimalActivity();
aa.eat(a);
aa.eat(d);
}
the result in the two cases will be: Animal is eating
but lets twist it some, lets have this:
public class Animal{
public void eat(){
System.out.println("Animal is eating");
}
}
then:
public class Dog extends Animal{
public void eat(){
System.out.println("Dog is eating");
}
}
then in the main class:
public static void main(String args[]){
Animal d=new Dog();
Animal a=new Animal();
a.eat();
d.eat();
}
now the result should be:
Animal is eating
Dog is eating
this is because overloading binds at compile time "static binding" while overriding binds at run time "dynamic binding"
Your current code will output
Animal is eating
However, in your main class, if you created an object of type Dog
and assigned it to Animal
, then your output will be Dog is eating
due to dynamic binding.
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
}
Even though a
is declared as Animal
it is pointing to an object of type Dog
. So, at runtime, the object type is determined and appropriate eat()
method is called.
One way to think of it is, method overloading
is statically bound and method overriding
is dynamically bound.
For non-static functions, you use static binding whenever the function is non-virtual, i.e. the final
keyword is applied to it and/or the function is private
. final
implies the function cannot be changed and the private
keyword implies it only has class scope. Otherwise, dynamic binding is used.
For static functions, static binding is always used. If a type A
is passed in, it will run A
's method, regardless of where A
references.