How does dynamic method dispatching work in Java
I learned earlier that a superclass variable that is referencing a subclass object can access only those parts of an object that are defined by the superclass. Then how can the second r.callMe() call B ‘s version of callMe() ? It should only call A ‘s version of callMe() again.
No it shouldn’t. Since the object is B (regardless of what the reference is), the object’s method will be called.
Initially r has the reference of A so it is same as A then r has a reference of B so it is calling the callme() of B .
callme() is defined in A. But it’ overridden in B, and since r is of type B, the overridden method in B is called. That’s what polymorphism is all about. If you had a foo() method defined only in B, then the compiler wouldn’t let you call r.foo(), because there is no foo() method defined in A, and the declared type of r is A.
5 Answers 5
. a superclass variable that is referencing a subclass object can access only those parts of object that are defined by superclass
That’s not entirely correct. In the end, the runtime calls the actual type of the object, regardless of the reference type. So r.callme() will actually call callme() defined in B , because r is a B object.
In the example above, B is called the object type, and A is called the reference type.
Let X be the compile-time type of the target reference of the method invocation.
[. ]If the invocation mode is virtual , and the declaration in S overrides X.m (§8.4.8.1), then the method declared in S is the method to be invoked, and the procedure terminates.
Let me make a rough guess at what they mean by «access only those parts [. ] defined by superclass»:
class A < void doSomething() < >> class B extends A < void doAnotherThing() < >>
A a = new B(); a.doAnotherThing(); // Not valid, because doAnotherthing() // is defined in class B.
In order to call doAnotherThing() , a type cast must be used:
What is dynamic method dispatch and how does it relate to inheritance? [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
3 Answers 3
What is meant by dynamic dispatch in Java […]?
Think of «dispatch» as «determining which method to call».
The «dynamic» part simply says that it is determined at runtime. That is, which method is to be called is determined at runtime.
why do we need it in the context of inheritance
Without inheritance / polymorphism we wouldn’t need this. The type of an expression would be decidable at compile time, and which method that would have been called at runtime would be known when compiling the program.
With inheritance / polymorphism we don’t know the concrete runtime type of an expression, thus which method to be called must be «dynamically» determined during runtime.
Without dynamic dispatch, virtual methods wouldn’t make sense, which is central for abstraction and encapsulation.
Can you please share some example to explain this point With inheritance / polymorphism we don’t know the concrete runtime type of an expression, thus which method to be called must be «dynamically» determined during runtime.
It’s quite simple: If you weren’t allowed to do List
got it now. And as I know there are 2 forms of Dynamic dispatch. single and double/multiple dispatch. Could you please share some light on those too. Preferably with an small example.
Single dispatch: You base your choice of method on a single input, for example the object type. Multiple dispatch: You base your choice on multiple input, for example the object type, and the argument types. In Java you can call different methods depending on which type of arguments you provide, (method overloading) but this mechanism works entirely in compile time. So for multiple dispatch, imagine this was decided in runtime: Object o = «hello»; m(o); and Object o = new Integer(5); m(o); could call different methods.
Ah, in java the two method calls will invoke the same method m , since both o s are Object types. If it supported multiple dispatch it should call two different methods. Thank you very much for clearing that piece. But anyway Java is not supporting multiple dispatch. Any idea why.
Other Answers discus the theory, this is an example to show why dynamic dispatch (also called late binding) is needed.
Assume you have an Class ‘Rectangle`.
And you have a subclass with rounded corners
public class RoundedRectangle extends Rectangle < @Override public void draw() < System.out.println("assume it is a rectangle with rounded corners"); >>
Now assume you have a method getting with an Parameter of Type Rectangle, which is used in the method to invoke the draw method
It the argument of this method is of class Rectangle then it will draw
But when the argument is of type RoundedRectangle, then we expect:
assume it is a rectangle with rounded corners
And this is where late binding is needed for: When the code compiles, it is not clear which method needs to be invoked by rect.draw(); I could be Rectangle.draw(), RoundedRectangle.draw(), or the draw method of any other yet not implemented subclass of Rectangle.
Summary (from the view of an developer):
So late binding means: invoke the method of given signature (Method name, and argument list) for an instance where is only known that it is of an specific class or subclass — but it is not known which class it is exactly. And when a method is overriden, then ivoke the overriding method.
So there is no Polymorphism vs. Late Binding — It is you need Late Binding when you have Polymorphism. In Java and in C++ (and i belive, in every other Object Oriented language too)
Dynamic Method Dispatch in Java Example
In Java, Dynamic method dispatch is a technique in which object refers to superclass but at runtime, the object is constructed for subclass.
In other words, it is a technique in which a superclass reference variable refers to a subclass object. It is also known as Upcasting in java.
Java uses this mechanism to resolve a call to an overridden method at runtime rather than compile time. The overridden method is called through the reference variable of a super class.
The determination of the method to be called is based on the object being referred to by the reference variable.
In the dynamic dispatch method technique, we can declare a super class reference variable equal to sub class object like this:
SuperClass sc = new ChildClass(); // sc is super class reference variable which is pointing to child class object.
Dynamic dispatch method is important because it is a process through which Java implements runtime polymorphism.
Let’s understand the dynamic method dispatch more clearly by different example programs.
Java Dynamic Method Dispatch Example Programs
Let’s create a Java program to illustrate Dynamic Method Dispatch using hierarchical inheritance.
Program source code 1:
package dynamicMethodDispatchProgram; public class A < void m1() < System.out.println("m1-A"); >> public class B extends A < // Overriding m1() method. void m1() < System.out.println("m1-B"); >> public class C extends B < // Overriding m1() method. void m1() < System.out.println("m1-C"); >> public class Test < public static void main(String[] args) < A a = new A(); // Object of type A. That is "a" is a reference variable of type A which is pointing to object of class A. a.m1(); B b = new B(); // Object of type B. "b" is a reference variable of type B which is pointing to object of class B. b.m1(); C c = new C(); // Object of type C. "c" is a reference variable of type C which is pointing to object of class C. c.m1(); A a2; // A reference variable of type A. a2 = b; // Reference a1 refers to Class B's object. a2.m1(); a2 = c; // Reference a1 refers to Class C's object. a2.m1(); B b2 = c; // Reference variable b2 of type B refers to class C's object. b2.m1(); >>
Output: m1-A m1-B m1-C m1-B m1-C m1-C
In the preceding program, we have created one super class called A and it’s two sub classes B and C. These sub classes override m1( ) method.
a) When a.m1(); will be executed, it will call method m1() of class A because reference variable “a” is pointing towards object of class A.
b) b.m1(); will call m1() of class B because reference variable “b” refers to object of class B.
c) c.m1(); will invoke m1() of class C because reference variable “c” is pointing towards object of class C.
2. When A a2 is declared, initially it will point to null.
a) a2.m1(); will call m1() of class B because “a2” is reference variable of type A but it is pointing towards class B’s object.
b) a2.m1(); will call m1() of class C. This is because “a2” is referring to class C’s object.
3. b2.m1(); will call m1() of class C because “b2” of type B is pointing to class C’s object.
If you have any problem understanding the above concept then first, I will recommend to you for going below the topic. In this topic, we have explained in detail the working concept of Java compiler and JVM which you can understand easily.
This is an example of dynamic method dispatch.
Let’s see the next example program.
Program source code 2:
package dynamicMethodDispatchProgram; public class X < X() < System.out.println("Parent class constructor"); m1(); >void m1() < System.out.println("Parent method"); >> public class Y extends X < Y() < System.out.println("Child class constructor"); >void m1() < System.out.println("Child class method"); >> public class Demo extends Y < public static void main(String[] args) < Y y = new Y(); y.m1(); X x = new Y(); x.m1(); Y y2 = new Demo(); y2.m1(); >>
Output: Parent class constructor Child class method Child class constructor Child class method Parent class constructor Child class method Child class constructor Child class method Parent class constructor Child class method Child class constructor Child class method
Explanation of flow of execution of the above program:
1. Inside the main() method of Demo class, when the statement A a = new A(); will be executed, the control of execution will be immediately transferred class Y’s constructor.
From there, super class constructor will be called and the control of execution will be transferred to class X’s constructor. The first output will be printed “Parent class constructor”.
2. From the super class constructor, m1() method of class Y will be called because the reference variable “y” is pointing to the object of class Y. The second output will be “Child class method”.
3. After the execution of m1() method, the control of execution will be again immediately transferred to class Y’s constructor. The third output will be “Child class constructor”.
4. y.m1(); will call m1() of class Y because “y” refers to object of class Y. The fourth output is “Child class method”.
Similarly, for the other two statements.
Let’s take another example program to understand concept of dynamic method dispatch in java.
Program source code 3:
package dynamicMethodDispatchProgram; public class XX < // Declaration of instance block. < m1(); >XX() < System.out.println("Parent class constructor"); m1(); >void m1() < System.out.println("Parent class method"); >> public class YY extends XX < YY() < System.out.println("Child class constructor"); >void m1() < System.out.println("Child class method"); >> public class Myclass < public static void main(String[] args) < XX x = new YY(); x.m1(); >>
Output: Child class method Parent class constructor Child class method Child class constructor Child class method
1. During the execution of above program, when the statement XX x=new YY(); will be executed, the constructor of class YY will be called and the control of execution will be immediately transferred to class YY’s constructor. From there, super class constructor XX() will be called.
But we know that before the execution of constructor, instance block is executed. Inside the instance block, m1() of class YY will be called because the reference variable “x” is pointing child class object. Therefore, the first output is “Child class method”.
2. After the complete execution of instance block, superclass constructor is executed. Therefore, the second output is “Parent class constructor”.
3. Inside the super class constructor, m1(); will call m1() method of class YY. Therefore, the third output is “Child class method”.
4. After the complete execution of superclass constructor, the control of execution will be transferred back to child class constructor. It will print “Child class constructor”. This is the fourth output.
5. x.m1(); will call m1() of class YY because the reference variable “y” is pointing to the object of class YY. Therefore, the fifth output is “Child class method”.
Let’s create a program where we will declare two method m1() and m2() in the parent class but in the child class, we will override only m1() method. We will also declare new method m3() in the child class. Let’s see the following source code.
Program source code 4:
package dynamicMethodDispatchProgram; public class ParentClass < void m1() < System.out.println("ParentClass m1"); >void m2() < System.out.println("ParentClass m2"); >> public class ChildClass extends ParentClass < void m1() < System.out.println("ChildClass m1"); >void m3() < System.out.println("ChildClass m3"); >> public class Mytest < public static void main(String[] args) < ParentClass p = new ChildClass(); p.m1(); p.m2(); // p.m3(); // The method m3() is undefined for the type ParentClass. >>
Output: ChildClass m1 ParentClass m2
In the dynamic method dispatch mechanism, there are two key points that you have to keep in mind.
1. The object can call the overriding method of child class as well as all non-overridden methods of the superclass. For example, in the preceding program, using reference variable “p”, we are called m1() and m2() methods.
2. The object cannot call methods that are newly added in the child class. For example, we have declared a new method m3() in the child class but it cannot be called because the method is undefined for type ParentClass.
Hope that this tutorial has covered almost all important points related to dynamic method dispatch technique in Java with realtime example programs. I hope that you will have understood this topic and enjoyed it.
Thanks for reading.
Next ⇒ Abstraction in Java ⇐ PrevNext ⇒