Analysis of dynamic binding principle in Java polymorphism

Time:2021-7-21

This article mainly introduces the dynamic binding principle of Java polymorphism analysis, the article through the example code is very detailed, for everyone’s study or work has a certain reference learning value, need friends can refer to

Polymorphism is a very important feature of object-oriented programming, which makes the program more readable and extensible.

  • It occurs in an inherited relationship.
  • Subclasses are required to override the methods of the parent class.
  • A reference to a parent type points to an object of a child type.

From the beginning to the end, polymorphism is for methods. There is no polymorphism for member variables in a class.

A reference variable of a base class that receives objects of different subclasses will call the corresponding methods of subclasses. This is actually the process of dynamic binding. Before you understand dynamic binding, add some concepts.

The type of the reference variable

Variables of reference type have two types: compile time type and run time type( Also called declarative type and actual type) for a simple example:

//Suppose the student class is a subclass of the person class
Person p = new Student();

Compile time type

  • It is also called declaration type, which is determined by the type of variable declaration.
  • The person in the above formula is the compile time type of the reference variable P.

Runtime type

  • Also called actual type, which is determined by the actual type that points to the object.
  • The student in the above formula is the runtime type of the reference variable P.

Method binding

Associating a method call with a method body is called a binding.

Static binding

Binding before program execution is called static binding, also known as pre binding. It is the default binding method in process oriented languages.

In Java, static binding is the method modified with private, static and final (which will be summarized after static and final) or constructor that can accurately make the compiler call which method.

Dynamic binding

Binding at runtime according to the runtime type of an object is called dynamic binding, or late binding. Of course, in Java, in addition to the static binding methods, the other methods are called by dynamic binding.

public class DynamicBinding {
  //Object is the superclass of all classes. According to the upward transformation, this method can accept any type of object
  public static void test(Object x) {
    System.out.println(x.toString());
  }

  public static void main(String[] args) {
    test(new PrimaryStudent());//Student
    test(new Student());//Student
    test(new Person());//Person
    test(new Object());//java[email protected]
  }
}

class Person extends Object {
  @Override
  public String toString() {
    return "Person";
  }
  public void run(){}
  public void count(int a){}
}

class Student extends Person {
  @Override
  public String toString() {
    return "Student";
  }
  public void jump(){}
}

class PrimaryStudent extends Student {
}

The formal parameters in the four statements that call methods are all object type at compile time. Note: reference variables can only call methods that are owned by compile time types.

They have different runtime types, so the interpreter runtime calls methods that are overridden in their respective types at runtime.

Reference variables of the same type show different behavior characteristics when calling the same method. This is the most intuitive manifestation of polymorphism.

Method table

We can also find that test (New primarystudent ()); The running result of is student, and the result is obvious, because the method of the parent class is not overridden in the primarystudent class. If the method is called in the way of dynamic binding, the virtual opportunity will first find a suitable method in this class. If not, it will always look for the parent class until it is found.

So, every time you call, you have to look up, and the time cost is bound to be very large. For this reason, the virtual machine creates a method table for each class in advance, which lists all the method signatures (excluding the return value type) and the methods actually called. In this way, you can directly look up the table when calling methods( It is worth mentioning that if you call the parent class method with super restriction, you will directly look up in the table of the parent class of the actual type.)

The following is the method table of the person class:

Person:
  //The object method signature is omitted below
  //xxx()-> Object.xxx()
  //Method signature - > method actually called
  toString()->Person.toString()
  run()->Person.run()
  count(int)->Person(int)

The following is the method table of student class:

Student:
  //The object method signature is omitted below
  //xxx()-> Object.xxx()
  //Method signature - > method actually called
  toString()->Student.toString()
  jump()->Student.jump()
  run()->Person.run()
  count(int)->Person(int)

The following is the method table of the primarystudent class (the primarystudent class is empty and directly inherits the student class)

PrimaryStudentt:
  //The object method signature is omitted below
  //xxx()-> Object.xxx()
  //Method signature - > method actually called
  toString()->Student.toString()
  jump()->Student.jump()
  run()->Person.run()
  count(int)->Person(int)

Therefore, test (New primarystudent()) is executed; Statement, the virtual machine will extract the primary student’s method table.

The virtual machine will search the table for the class that defines the toString signature. At this time, the virtual machine already knows that it needs to call the toString () method of the student type.

Finally, the call method is finished.

Dynamic binding greatly improves the scalability of the program. For example, I want to add a new teacher class, which can be directly inherited from the person class, and then

The reference of the object class points to the teacher object without any other code adjustment. Dynamic binding is done automatically, which is quite comfortable.

The above is the whole content of this article, I hope to help you learn, and I hope you can support developer more.

Recommended Today

How to use Lamar in ASP. Net core

ASP. Net comes with a minimalist coreOut of the boxIn fact, you can also use third-party dependency injection containersDependency injection containerInstead of it, dependency injection is a design pattern that can effectively decouple objects and improve unit testing and maintainability. You can use itDependency injectionTo improve your code design, instead of new objects everywhere. Lamar […]