• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Dan's Questions: Dynamic Method Invocation

 
Ranch Hand
Posts: 150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello friends
Please consider the following 2 examples (they are simplied form of Dan's Chapter 6/Exam 1, Q17 and Q20 respectively):

This will print: B

This will print: A
In the first example, m1 is overridden and in the second, it's overloaded. Is it true that the method which gets invoked at run-time depends upon whether it's overridden or overloaded? If yes, it would surprising because this distinction is 'not' mentioned in the Khalid Mughal book, which I rate very highly.
Thanks
Harwinder
[ October 21, 2003: Message edited by: Harwinder Bhatia ]
 
Author
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think this is just a simple coding error. Both examples print A
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Keep in mind that overloading and overriding really have nothing to do with one another. They are not mere variations on the same thing - they are totally different.
Overloading in the practice of using the same method name with multiple differing signatures. This, in effect, produces multiple unique methods as each signature is different.
Overriding, on the other hand, uses the EXACT SAME method signature repeatedly in order to achieve dynamic behavior of objects.
In your first example (which has a typo on the method signature, I believe), you have overriddent the method m1 by using an identical method signature in the subclass. Doing so causes the JVM to utilize dynamic method binding and results in the method m1 to be executed in the subclass (which is the run-time type of the variable), rather than the parent class.
In the second example, we are overloading, not overriding. Therefore, as the method m1 is not overridden, there is absolutely no reason for the JVM to use dynamic method binding. Instead, it goes right to the compile-time type of the variable (as opposed to the run-time type used above), which is A, and invokes the proper method.
I hope that helps.
 
Ranch Hand
Posts: 168
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you override a method, you replace the method with an implementation in the subclass.
When you overload a method, you create a new method with the same name as a method that already exists, but with a different argument list.
In the second example, s/b . So the next line [code]b1.m1(b2);[code] invokes the original method instead of the overloaded method, because the original method takes a type A as an argument.
To put it in another way, in the first example, type B has a single method which we could call 'void B.m1()'. In the second example, type B has two methods, which we would call 'void B.m1( A)' and 'void B.m1( B)'. Since the two methods have the same name, the compiler chooses which method to invoke by the types and numbers of the arguments.
 
Harwinder Bhatia
Ranch Hand
Posts: 150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Doug & Corey for the express replies.
There was indeed a typo, which I just corrected (there is no m2). I compiled the examples again and verified the results.
Corey,
I am pretty clear on the first example (I think I am), but the second one seems contradictory. I understand the distinction between the 2 cases very clearly but what I don't understand is the "why" this distinction is in place.
If method m1 is overloaded in the subclass and a call b1.m1(b2) is made, the argument type should determine which version of the overloaded method should get invoked. At run-time, b1 is essentially a reference to class B object anyways.
When "Dynamic Method Invocation" is applied in the first case, why isn't it applied in the second? What is the rationale behind it?
Thanks
Harwinder
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Harwinder Bhatia:

When "Dynamic Method Invocation" is applied in the first case, why isn't it applied in the second? What is the rationale behind it?


It isn't applied in the second case because there is no reason to apply it. Dynamic method invocation is only used when a method is overridden. In the second example, there is no overridden method. Therefore, dynamic method invocation is not used.
Let's take a look at that example and see what we really have going on.

In this case, we have creates two new objects. Both of these objects have a run-time type of B, but b1 has a compile-time type of A while b2 has a compile-time type of B. Now, if we remember what we have done with our methods, we'll see something that is teh key to this whole thing.
Notice that, in class A, we have this method signature:

While, in class B, we have this method signature:

So, what does that mean? Well, class B extends class A. Therefore, class B inherits the method m1(A) from class A. However, class B overloads that method (it DOES NOT override it). The result is that class A has one method named m1 while class B has two methods named m1.
When you compile this, the compiler is going to try to determine which method should be invoked. It starts by looking at the type of the variable on which the method is being invoked. The compile-time type of b1 is A, so the compiler looks into the definition of the class A to find a suitable method. It finds one (and only one as the overloaded method is in B, not A). It then checks to see if that method is overridden. It is not, so this is the appropriate method to invoke.
I hope that makes this a bit clearer for you. If you really want to get to the gritty details of this, check out the JLS: §15.12 Method Invocation Expressions.
 
Harwinder Bhatia
Ranch Hand
Posts: 150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Corey
Thanks for your elaborate response. It does make things a lot clearer. As I said, I understand how method invocation works. I followed the link which you gave and read through some part of the JLS too.


It isn't applied in the second case because there is no reason to apply it.


Well, I have been thinking of a "reason" and I think I have one (I'm just thinking out loud here).
In case a subclass overloads a method in the superclass, why doesn't Java language adopt the policy of "closest match", like it is the case in resolving overloaded methods in the same class, especially when the runtime type of the object is the subclass type anyways?
Wouldn't it have made things more logical and consistent in 2 ways:
1. Always apply dynamic method invocation
2. and in case a superclass method is overloaded by subclass, always try to find the closest match.
Thanks
Harwinder
 
Is that a spider in your hair? Here, threaten it with this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic