Problems with static binding and dynamic binding in Java

I read some articles on static binding and dynamic binding in Java. And I have the following question (I searched a lot, but have not yet found a mention of this):

For example, I have the following lines of code:

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

What we already know is at compile time , the compiler checks to see if the method definition for speak() exists in the Person class and calls it if it exists. And at runtime, it will call the speak() method of the actual object that a points to (the actual object in this case is explicitly Student )

So my question is why doesn’t it call the speak() method of the Student class at compile time , but until the runtime does it? Are there any reasons for this?

+5
source share
3 answers

When the code compiles, it is sometimes unclear which method needs to be called. It can only be determined 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 accepts any object that passes the ISA Animal test and calls the corresponding method of this object. As you can see, it also removes code duplication, since we can use the same method for different types of objects.

Hope this is the address of your concern.

+3
source

To understand this topic, you need to know what compilation processes and runtimes are in general. In short, when you create your application compiler, it goes through all your code and checks for consistency, security, and the ability to run. If there is no error created by the compiler, it generates class files from your source code ( java files). When the application is running, it means that your class files are loaded into memory, and the JVM follows the instructions for your application.

In your example:

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

Compilation process: The compiler checks this line: Person a = new Student(); for type safety (compatibility). So, if a student is a compilation of a person proceeds to the next line, he fails. In the next line: a.speak(); the compiler looks at type a , finds that it is Person and looks for the speak() method in Person . If this method is not based on the compiler, the compilation process fails.

Execution Process: When the JVM executes this line: Person a = new Student(); it goes through the initialization process from the top (parent class) to the bottom (child class). In the next line: a.speak(); The JVM detects the student object via a link, looks for the speak() method, if it is based on student , then executes it, otherwise it runs the speak() method from the parent class Person .

Other examples from the subject of inheritance:

 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 why public and protected fields and methods are available b.speakALot(); // calling speakALot() method of student object 
+3
source

If I just write a general purpose class to test any type of vehicle as follows.

 public class Workshop{ public boolean test(Vehicle vehicle){ vehicle.start(); vehicle.stop(); //...more code return true; } } 

I can only compile this code with the vehicle type, although none of the child classes of the vehicle were written. In general, they use this ability to provide processing based on a generic type in the absence of specific types (clients can freely expand the hierarchy of child classes). In such cases, the compiler will simply make sure that the vehicle will have at least one implementation (a null implementation such as {} is also acceptable) will be available so as not to break the code.

0
source

Source: https://habr.com/ru/post/1273601/


All Articles