Hi Ashish, Because x is of type XTC and the only method that you have defined in that class accepts 2 params: XTC and int Then you have overloaded that method inside the XYZ class. So that is the method that gets called (the one on line 2). The compiler method: 1. Start at reference type class --> XTC 2. Look for closest fit with given params: ZZY can be widened to XTC 'c' can be widened to int 3. Check actual type for overridden method If found then call it --> line 2 method If not then call the one found in step 2. This is also the same reason why: z.trance( (ZZY)x, 'c' ); would call the method on line 3. Regards, Manfred. [ April 24, 2002: Message edited by: Manfred Leonhardt ]
Good question! This one's pretty tricky, but I think I've got it figure out. The key is that empty method in the class XTC. This gets into the nit-picky details about how the correct method is found to be executed. You can read pages on this topic in the JLS, §15.12.4 Runtime Evaluation of Method Invocation. However, I'll try to clear this up here. Here's a snippet from the JLS, §18.104.22.168 Locate Method to Invoke:
Let X be the compile-time type of the target reference of the method invocation.
1. If class S contains a declaration for a non-abstract method named m with the same descriptor (same number of parameters, the same parameter types, and the same return type) required by the method invocation as determined at compile time (�15.12.3), then: - If the invocation mode is super or interface, then this is the method to be invoked, and the procedure terminates. - If the invocation mode is virtual, and the declaration in S overrides (�22.214.171.124) X.m, then the method declared in S is the method to be invoked, and the procedure terminates. 2. Otherwise, if S has a superclass, this same lookup procedure is performed recursively using the direct superclass of S in place of S; the method to be invoked is the result of the recursive invocation of this lookup procedure.
What happens is the JVM starts with the compile-time type of the target object. The target object is the object referenced by x. The compile-time type of x is XTC, even though it's run-time type is ZZY. The JVM first looks in the the compile-time class (XTC) for a matching method. It finds a method that matches (that's the empty method up there). Next, the JVM has to determine if this is the method that should be executed or if this method has been overridden in the subclass. It has to do this check because the run-time type of x is ZZY. Indeed, there is a method defined in ZZY that overrides this method. Remember, when you override a method, the parameters have to match exactly. Therefore, the overriding method (the one that take an int, not a char) is invoked by the JVM. It would seem that the other method is a better match, but due to the overridden method, the one that takes an int is called. Now, if you remove that empty method from the class XTC, you'll see that the method that takes a char is invoked, as it is the best match based on the parameters passed. I hope that helps clear things up. Where did you find that question? That one is pretty rough. Corey
Absolutely, Corey ! This one had me going in a loop.. I even took it & tried to run it on my server. Made it simpler... took out the integer and the char parameters from the trance method... and witnessed that the trance with parameter of base class was being called inspite of the cast in the call. It was almost like it ignores the cast altogether! A very good question, indeed!