In object-oriented programming, dynamic binding ensures that method calls are resolved at runtime based on the actual object type rather than the reference type. This mechanism applies exclusively to methods, not to fields.
Key Principles:
- Method calls are bound to the runtime type of the object. If the method isn't found in the runtime type, the inheritance hierarchy is searched upward.
- Field access follows compile-time binding - fields are accessed based on where they are declared, not the runtime type.
Example 1: Complete Method Overriding
class BaseClass {
public int value = 10;
public int calculateSum() {
return fetchValue() + 10;
}
public int computeTotal() {
return value + 10;
}
public int fetchValue() {
return value;
}
}
class DerivedClass extends BaseClass {
public int value = 20;
public int calculateSum() {
return value + 20;
}
public int fetchValue() {
return value;
}
public int computeTotal() {
return value + 10;
}
}
public class BindingDemo {
public static void main(String[] args) {
BaseClass obj = new DerivedClass();
System.out.println(obj.calculateSum()); // Output: 40
System.out.println(obj.computeTotal()); // Output: 30
}
}
In this example, both methods are overridden in the derived class. The runtime type (DerivedClass) determines which method implementation executes.
Example 2: Partial Method Overriding
class BaseClass {
public int value = 10;
public int calculateSum() {
return fetchValue() + 10;
}
public int computeTotal() {
return value + 10;
}
public int fetchValue() {
return value;
}
}
class DerivedClass extends BaseClass {
public int value = 20;
// calculateSum() not overridden - inherits from BaseClass
// computeTotal() not overridden - inherits from BaseClass
public int fetchValue() {
return value;
}
}
public class BindingDemo {
public static void main(String[] args) {
BaseClass obj = new DerivedClass();
System.out.println(obj.calculateSum()); // Output: 30
System.out.println(obj.computeTotal()); // Output: 20
}
}
When calculateSum() is called, it uses the inherited BaseClass implementation. However, fetchValue() within that method undergoes dynamic binding and executes the DerivedClass version, returning 20. The calculation becomes 20 + 10 = 30.
For computeTotal(), the field access value uses compile-time binding, accessing the BaseClass field value of 10, resulting in 10 + 10 = 20.
Important Restriction
When a reference has a compile-time type of the parent class and runtime type of a child class, you cannot directly access methods that are exclusively defined in the child class without explicit casting.