Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with static binding and dynamic binding in Java

I've read through some articles about static binding and dynamic binding in Java. And I have the following question (I've searched a lot but not found any mention about it yet):

For example, I have the following lines of code:

Person a = new Student(); // Student is a subclass of Person
a.speak();

What we've already known is that at compile-time, the compiler will checks whether there exist method definition for speak() in class Person and call it if it exists. And at run-time, it will call the speak() method of the actual object to which a is pointing (The actual object in this case is clearly Student)

So my question is why it doesn't directly call the speak() method of class Student at compile-time, but wait until run-time to do that? Are there any reasons behind this?

like image 358
DunDev Avatar asked Nov 23 '17 04:11

DunDev


2 Answers

When the code compiles, sometimes,it is not clear which method needs to be invoked.It can be determined only at runtime.

Take this simple code as an example.

class Animal{   

    public void makeNoise(){
       System.out.println("Default");
    };
}

class Dog extends Animal{

    //override the makeNoise()
    public void makeNoise(){
        System.out.println("Woof");
    };
}

class Cat extends Animal{

        //override the makeNoise()
        public void makeNoise(){
            System.out.println("Meow");
        };
    } 

public class Sounds{

    public static void AnimalSounds(Animal animal){
    animal.makeNoise();
    }

    public static void main(String args[]){

        Animal dog = new Dog();     
        Animal cat = new Cat(); 
        AnimalSounds(dog);
        AnimalSounds(cat);  
    }
}

AnimalSounds(Animal animal) method takes any object that passes ISA test of Animal and invoke the respective method of that object. As you can see, it removes code duplication as well since we can use the same method on different types of objects.

Hope this address your concern.

like image 84
Supun Amarasinghe Avatar answered Sep 20 '22 05:09

Supun Amarasinghe


To understand this topic you should know what are compilation and run-time processes in general. In short, when you build your app compiler goes through all your code and checks for consistency, safety and run-ability. If there is no error founded by compiler it generates class files from your source code (java files). When the app is running it means that your class files are loaded into memory and JVM executing your app instruction by instruction.

From your example:

Person a = new Student(); // Student is a subclass of Person
a.speak();     

Compilation process: Compiler checks this line: Person a = new Student(); for type safety (compatibility). So, if student is a person compilation goes to next line else it fails. In next line: a.speak(); compiler looks at a type, found that it's a Person and looks for speak() method at Person type. If that method is not founded by compiler compilation process fails.

Runtime process: When JVM executes this line: Person a = new Student(); it goes through initialization process from top (parent class) to bottom (child class). In next line: a.speak(); JVM founds student object through reference a looks for method speak() if it's founded in Student then executes it, otherwise it runs speak() method from parent class Person.

Another examples from inheritance subject:

class Person {
    public void speak() {}
    public void think() {}
}

class Student extends Person {
    @Override
    public void speak() {}
    public void speakALot() {}
}

Person a = new Student();
a.speak(); // calling overrided version of speak() 
a.think(); // since this method is not overrided in child class it will be called from parent class
a.speakALot(); // since Person doesn't know anything about specific methods of derived classes compilation fails 

Student b = new Student();
b.speak(); // calling speak() method of student object
b.think(); // inheritance trick, child class keeps reference to its base class and that's why public and protected fields and methods are available
b.speakALot(); // calling speakALot() method of student object
like image 43
Ibrokhim Kholmatov Avatar answered Sep 22 '22 05:09

Ibrokhim Kholmatov