What is Dynamic Method Dispatch in Java?
Dynamic method dispatch in Java is a mechanism that helps to call an overridden method at runtime by creating referenced objects. It is the same as runtime polymorphism. Dynamic method dispatch in Java uses upcasting. Upcasting is a process to convert the reference variable of the child class to the reference variable of the parent class. Let us understand this concept with the help of an example.
Upcasting
Upcasting in object-oriented programming refers to treating an object of a subclass as an object of its superclass. This process occurs automatically in many programming languages, including Java and C++, and is used to achieve flexibility and code reuse.
In upcasting, when a subclass object is assigned to a superclass reference, the compiler only allows access to the properties and methods of the superclass, even though the object itself is of the subclass. This enables polymorphism, allowing one reference type to refer to different objects at runtime.
Here’s an example in Java:
Java
class Animal {
void makeSound() {
System.out.println("Animal makes sound");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog(); // Upcasting
animal.makeSound(); // Can only access methods from Animal class
}
}
You can also try this code with Online Java Compiler
Run Code
Output
Animal makes sound
In this example, the Dog object is treated as an Animal, but only Animal methods are accessible. This is useful when you want to write generic code that can work with any subclass of a parent class, promoting reusability.
Example of Dynamic Method Dispatch in Java
Here is an example to understand dynamic method dispatch or Runtime Polymorphism in Java.
Java
class CompanyOfCars {
// Creating a company() method
public void company() {
System.out.println("Welcome to our car gallery.");
}
}
// Bmw class that extends CompanyOfCars
class Bmw extends CompanyOfCars {
public void company() {
System.out.println("BMW is a great company.");
}
}
// Mercedes class that extends CompanyOfCars
class Mercedes extends CompanyOfCars {
public void company() {
System.out.println("Mercedes gives you royalty.");
}
}
class Main{
public static void main(String args[]){
// Creating object for class CompanyOfCars
CompanyOfCars obj=new CompanyOfCars();
obj.company();
// Creating object for class Bmw
obj=new Bmw();
obj.company();
// Creating object for class Mercedes
obj=new Mercedes();
obj.company();
}
}
You can also try this code with Online Java Compiler
Run Code
Output
Welcome to our car gallery.
BMW is a great company.
Mercedes gives you royalty.
Explanation
In this example, we have created a superclass CompanyOfCars. This class extends two subclasses, Bmw and Mercedes. These two subclasses override a method company(). In this example, we have created objects of these subclasses differently if we compare them with the method overriding’s example. This mechanism of calling the overridden methods at runtime is called dynamic method dispatch in Java.
As mentioned above in the example, the method call is connected to the method body. This process is known as binding. Two types of binding are possible:
1. Static Binding: In this type of binding, the type of the object is determined at the time of compilation.
2. Dynamic Binding: In this type of binding, the type of the object is determined at the runtime.
Example of Runtime Polymorphism: Shape
In runtime polymorphism, a superclass reference can refer to subclass objects, and the method to be called is determined at runtime. Consider an example with a superclass Shape and its subclasses Circle and Rectangle.
Java
class Shape {
void draw() {
System.out.println("Drawing a shape");
}
}
class Circle extends Shape {
void draw() {
System.out.println("Drawing a circle");
}
}
class Rectangle extends Shape {
void draw() {
System.out.println("Drawing a rectangle");
}
}
public class Main {
public static void main(String[] args) {
Shape shape;
shape = new Circle(); // Runtime polymorphism
shape.draw(); // Outputs: Drawing a circle
shape = new Rectangle(); // Runtime polymorphism
shape.draw(); // Outputs: Drawing a rectangle
}
}
You can also try this code with Online Java Compiler
Run Code
Output
Drawing a circle
Drawing a rectangle
Here, the draw() method is overridden in both subclasses, and which version of draw() gets called is determined at runtime based on the object assigned to shape. This is runtime polymorphism in action.
Example of Runtime Polymorphism: Animal
In this example, the superclass Animal has a method sound(), and different animals (subclasses like Dog and Cat) provide their own implementation of sound().
Java
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
void sound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal animal;
animal = new Dog(); // Runtime polymorphism
animal.sound(); // Outputs: Dog barks
animal = new Cat(); // Runtime polymorphism
animal.sound(); // Outputs: Cat meows
}
}
You can also try this code with Online Java Compiler
Run Code
Output
Dog barks
Cat meows
Here, the method sound() is overridden in Dog and Cat, and the method call is determined at runtime based on the object assigned to the animal reference.
Runtime Polymorphism with Data Members
In runtime polymorphism, only methods are overridden, not data members. The method resolution happens at runtime, but data members are resolved at compile-time based on the reference type. Here's an example:
Java
class Parent {
int value = 10;
void display() {
System.out.println("Value from Parent: " + value);
}
}
class Child extends Parent {
int value = 20;
void display() {
System.out.println("Value from Child: " + value);
}
}
public class Main {
public static void main(String[] args) {
Parent obj = new Child(); // Runtime polymorphism
obj.display(); // Outputs: Value from Child: 20
System.out.println("Data member value: " + obj.value); // Outputs: 10
}
}
You can also try this code with Online Java Compiler
Run Code
Output
Value from Child: 20
Data member value: 10
In this case, the display() method shows runtime polymorphism, calling the Child class method. However, the data member value is resolved using the Parent class, showing that data members do not exhibit runtime polymorphism.
Advantages of Dynamic Method Dispatch
There are various advantages of dynamic method dispatch in Java:
-
This allows for polymorphism. That’s why we can write more flexible and maintainable code that can be extended and reused.
-
It helps us to reuse the code because of method overriding.
-
It makes our code more flexible. We can change the behavior of the subclass method without changing the behavior of the parent class method.
- It allows us to define abstract methods in a superclass and implement them in subclasses.
Disadvantages of Dynamic Method Dispatch
Along with some advantages, dynamic method dispatch in Java also has some disadvantages:
-
It adds some performance overhead to method calls. The JVM(Java Virtual Machine) has to determine the actual class of an object at runtime before it can call the appropriate method.
-
It can add complexity to code. Developers must understand the relationships between classes and how inheritance and method overriding work.
-
It can cause unintended consequences if a subclass overrides a method in a superclass that was not intended to be overridden.
- It can also introduce security issues if malicious code can access objects of unexpected types or override methods in unexpected ways.
Application of Dynamic Method Dispatch
-
Enables Runtime Polymorphism: Dynamic method dispatch allows a method to be overridden in subclasses and ensures that the correct method is called at runtime, not compile time.
-
Simplifies Code Maintenance: It promotes flexibility by allowing changes to specific subclasses without altering the code in the superclass.
-
Supports Method Overriding: Subclasses can provide their own implementation of a superclass method, ensuring that the subclass version is executed during runtime.
-
Decouples Code: Reduces dependency between classes, making it easier to extend the codebase with new functionalities without modifying existing code.
- Useful in Frameworks: Dynamic method dispatch is heavily used in frameworks where behaviors are defined in a base class but executed in derived classes.
Frequently Asked Question
Why is dynamic dispatch dynamic?
Dynamic dispatch is dynamic because the method to be executed is selected during runtime based on the object's actual type, not the reference type.
Is dynamic dispatch the same as polymorphism?
Yes, dynamic dispatch is a form of runtime polymorphism where the method to be invoked is determined during runtime.
How does dynamic dispatch work?
Dynamic dispatch works by determining the method to be executed at runtime, depending on the actual object's type, allowing for method overriding.
What do you mean by polymorphism?
Polymorphism is an one of the important component of OOPs. It refers to the ability of objects of different classes to be treated as if they are objects of the same class.
What do you mean by runtime polymorphism?
Runtime polymorphism is also known as late binding. It allows a program to determine which method to invoke at runtime rather than at compile-time.
Conclusion
In this article, we have discussed the concept of dynamic method dispatch in Java. We have also discussed some examples based on this concept. We have also covered its advantages and disadvantages. You can check out our other blogs to enhance your knowledge:
We hope this blog helped you to understand the dynamic method dispatch in Java. You can refer to our guided paths on Code360.. You can check our course to learn more about DSA, DBMS, Competitive Programming, Python, Java, JavaScript, etc.
To practice and improve yourself in the interview, you can also check out Top 100 SQL problems, Interview experience, Coding interview questions, and the Ultimate guide path for interviews.
Happy Learning!!