Dynamic binding and static binding have to do with inheritance. In Java, any derived class object can be assigned to a base class variable. For instance, if you have a class named Animal from which you derived the class Dog, you can do this:
Animal myAnimal = new Dog();
The variable on the left is type Animal, but the object on the right is type Dog. As long as the variable on the left is a base class of Dog, you are allowed to do that. Being able to do assignments like that sets up what is called “polymorphic behavior”: if the Dog class has a method that is the same as a method in the Animal class, then the version of the method in the Dog class will be called. For instance, if both classes define a method called show(), and you do this:
myAnimal.show();
the version of show() in the Dog class will be called. Even though you are using an Animal variable type to call the method show(), the version of show() in the Animal class won’t be executed. Instead, it is the version of show() in the Dog class that will be executed. The type of the object that is assigned to the Animal variable determines the method that is called.
So, when the compiler scans the program and sees a statement like this:
myAnimal.show();
it knows that myAnimal is of type Animal, but the compiler also knows that myAnimal can be a reference to any class derived from Animal. Therefore, the compiler doesn’t know what version of show() that statement is calling. It’s not until the assignment:
Animal myAnimal = new Dog();
is executed that the version of show() is determined. Since the assignment doesn’t occur until runtime, it’s not until runtime that the correct version of show() is known. That is known as “dynamic binding” or “late binding”: it’s not until your program performs some operation at runtime that the correct version of a method can be determined. In Java, most uses of inheritance involve dynamic binding.
“Static binding” or “early binding” occurs when the compiler can readily determine the correct version of something during compile time, i.e. before the program is executed. In Java, member variables have static binding because Java does not allow for polymorphic behavior with member variables. That means if both the Animal class and the Dog class have a member variable with the same name, it’s the base class version that is used. For instance, if you set up the necessary ingredients for polymorphic behavior:
Animal myAnimal = new Dog();
and both the Animal and Dog classes have a String member variable ‘type’, then if you do this:
String str = myAnimal.type;
the value of ‘type’ can be fully determined by the compiler. Because polymorphic behavior is not allowed for member variables, that statement is referring to the value of ‘type’ in the Animal class–not the Dog’s value for ‘type’. The result is: with member variables, it’s the type of the variable(e.g. myAnimal) that determines which version is called–not the type of the object the variable refers to(e.g. Dog). When the compiler is able to figure out the correct version of something during compilation, that’s known as static binding.
Here is an example of both dynamic and static binding:
class Animal
{
public String type = “mammal”;
public void show()
{
System.out.println(“The animal is a: ” + type);
}
}
class Dog extends Animal
{
public String type; //same member variable name as in base class
public Dog(String type)
{
this.type = type;
}
public void show() //same method signature as in base class
{
System.out.println(“The dog is a: ” + type);
}
}
public class DemoStaticBinding
{
public static void main(String[] args)
{
Animal doggie = new Dog(“daschund”);
doggie.show(); // “The dog is a: daschund” (dynamic binding)
System.out.println(“The type is: ” + doggie.type); //”The type is: mammal” (static binding)
}
}
Animal myAnimal = new Dog();
The variable on the left is type Animal, but the object on the right is type Dog. As long as the variable on the left is a base class of Dog, you are allowed to do that. Being able to do assignments like that sets up what is called “polymorphic behavior”: if the Dog class has a method that is the same as a method in the Animal class, then the version of the method in the Dog class will be called. For instance, if both classes define a method called show(), and you do this:
myAnimal.show();
the version of show() in the Dog class will be called. Even though you are using an Animal variable type to call the method show(), the version of show() in the Animal class won’t be executed. Instead, it is the version of show() in the Dog class that will be executed. The type of the object that is assigned to the Animal variable determines the method that is called.
So, when the compiler scans the program and sees a statement like this:
myAnimal.show();
it knows that myAnimal is of type Animal, but the compiler also knows that myAnimal can be a reference to any class derived from Animal. Therefore, the compiler doesn’t know what version of show() that statement is calling. It’s not until the assignment:
Animal myAnimal = new Dog();
is executed that the version of show() is determined. Since the assignment doesn’t occur until runtime, it’s not until runtime that the correct version of show() is known. That is known as “dynamic binding” or “late binding”: it’s not until your program performs some operation at runtime that the correct version of a method can be determined. In Java, most uses of inheritance involve dynamic binding.
“Static binding” or “early binding” occurs when the compiler can readily determine the correct version of something during compile time, i.e. before the program is executed. In Java, member variables have static binding because Java does not allow for polymorphic behavior with member variables. That means if both the Animal class and the Dog class have a member variable with the same name, it’s the base class version that is used. For instance, if you set up the necessary ingredients for polymorphic behavior:
Animal myAnimal = new Dog();
and both the Animal and Dog classes have a String member variable ‘type’, then if you do this:
String str = myAnimal.type;
the value of ‘type’ can be fully determined by the compiler. Because polymorphic behavior is not allowed for member variables, that statement is referring to the value of ‘type’ in the Animal class–not the Dog’s value for ‘type’. The result is: with member variables, it’s the type of the variable(e.g. myAnimal) that determines which version is called–not the type of the object the variable refers to(e.g. Dog). When the compiler is able to figure out the correct version of something during compilation, that’s known as static binding.
Here is an example of both dynamic and static binding:
class Animal
{
public String type = “mammal”;
public void show()
{
System.out.println(“The animal is a: ” + type);
}
}
class Dog extends Animal
{
public String type; //same member variable name as in base class
public Dog(String type)
{
this.type = type;
}
public void show() //same method signature as in base class
{
System.out.println(“The dog is a: ” + type);
}
}
public class DemoStaticBinding
{
public static void main(String[] args)
{
Animal doggie = new Dog(“daschund”);
doggie.show(); // “The dog is a: daschund” (dynamic binding)
System.out.println(“The type is: ” + doggie.type); //”The type is: mammal” (static binding)
}
}
No comments:
Post a Comment