Dynamic Binding
Tags: java, programming, learning, beginners
Published: 2024-06-10 11:55:13

A method can be implemented in several classes along the inheritance chain. The JVM decides which method is invoked at runtime. A method can be defined in a superclass and overridden in its subclass. For example, the **toString()** method is defined in the **Object** class and overridden in **GeometricObject**.

Consider the following code:

`Object o = new GeometricObject();
System.out.println(o.toString());`

Which **toString()** method is invoked by **o**? To answer this question, we first introduce two terms: declared type and actual type. A variable must be declared a type. The type that declares a variable is called the variable’s _declared type_. Here **o**’s declared type is **Object**. A variable of a reference type can hold a **null** value or a reference to an instance of the declared type. The instance may be created using the constructor of the declared type or its subtype. The _actual type_ of the variable is the actual class for the object referenced by the variable. Here **o**’s actual type is **GeometricObject**, because **o** references an object created using **new GeometricObject()**. Which **toString()** method is invoked by **o** is determined by **o**’s actual type. This is known as _dynamic binding_.

Dynamic binding works as follows: Suppose an object **o** is an instance of classes **C1**, **C2**, . . . , **Cn-1**, and **Cn**, where **C1** is a subclass of **C2**, **C2** is a subclass of **C3**, . . . , and **Cn-1** is a subclass of **Cn**, as shown in Figure below. That is, **Cn** is the most general class, and **C1** is the most specific class. In Java, **Cn** is the **Object** class. If **o** invokes a method **p**, the JVM searches for the implementation of the method **p** in **C1**, **C2**, . . . , **Cn-1**, and **Cn**, in this order, until it is found. Once an implementation is found, the search stops and the first-found implementation is invoked.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrq5w97hedgmwxivjmcr.png)

The program below gives an example to demonstrate dynamic binding.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anjms7ek34pu3fpn3hgm.png)

`Student
Student
Person
java.lang.Object@130c19b`

Method **m** (line 12) takes a parameter of the **Object** type. You can invoke **m** with any object (e.g., **new GraduateStudent()**, **new Student()**, **new Person()**, and **new Object()**) in lines 6–9).

When the method **m(Object x)** is executed, the argument **x**’s **toString** method is invoked. x may be an instance of **GraduateStudent**, **Student**, **Person**, or **Object**. The classes **GraduateStudent**, **Student**, **Person**, and **Object** have their own implementations of the **toString** method. Which implementation is used will be determined by x’s actual type at runtime. Invoking **m(new GraduateStudent())** (line 6) causes the **toString** method defined in the **Student** class to be invoked.

Invoking **m(new Student())** (line 7) causes the **toString** method defined in the **Student** class to be invoked; invoking **m(new Person())** (line 8) causes the **toString** method defined in the **Person** class to be invoked; and invoking **m(new Object())** (line 9) causes the **toString** method defined in the **Object** class to be invoked.

Matching a method signature and binding a method implementation are two separate issues. The _declared type_ of the reference variable decides which method to match at compile time. The compiler finds a matching method according to the parameter type, number of parameters, and order of the parameters at compile time. A method may be implemented in several classes along the inheritance chain. The JVM dynamically binds the implementation of the method at runtime, decided by the actual type of the variable.