[ B extends A, C extends B, each implements/overrides showMe() ]
> Question: how can I [in class C] access class A's showMe()?
> I'm suspecting this cannot be done without modifying codes
> outside of class C.
1) if you need to do this, you've probably got a broken object model. You
shouldn't know or care about it's implementation beyond what method signatures
are available to you.
2) If you really need it, you could use reflection.
this.getClass().getSuperclass().getSuperclass().getMethod("showMe", null)
will get you the Method you want to call.
--
Mark Rafn dagon@dagon.net <http://www.dagon.net/>
Patricia Shanahan - 02 Jan 2008 00:27 GMT
> [ B extends A, C extends B, each implements/overrides showMe() ]
>
[quoted text clipped - 5 lines]
> shouldn't know or care about it's implementation beyond what method signatures
> are available to you.
Strongly agree. Either C should not be calling A's method, or B's
version does not do the same job as A's method, and should have a
different name.
> 2) If you really need it, you could use reflection.
> this.getClass().getSuperclass().getSuperclass().getMethod("showMe", null)
> will get you the Method you want to call.
This does not seem to work. However, to be fair, I was not really
expecting it to work so I may have missed something. Please review. I get:
Direct showMe call
C
Super call
B
Refection call
C
when I run the following. Note that I would only throw "Exception" in a
test program, where I want any problem in the reflection, no matter what
it is, to flow to the top and crash the program.
public class ReflectionTest {
public static void main(String[] args)
throws Exception {
new C().test();
}
static class A {
public void showMe() {
System.out.println("A");
}
}
static class B extends A {
public void showMe() {
System.out.println("B");
}
}
static class C extends B {
public void showMe() {
System.out.println("C");
}
public void test() throws Exception {
System.out.println("Direct showMe call");
showMe(); // prints C
System.out.println("Super call");
super.showMe(); // prints B
System.out.println("Refection call");
Method grandparentMethod =
getClass().getSuperclass().getSuperclass()
.getMethod("showMe", (Class[]) null);
grandparentMethod.invoke(this, new Object[0]);
}
}
}
Mark Rafn - 02 Jan 2008 04:18 GMT
>This does not seem to work. However, to be fair, I was not really
>expecting it to work so I may have missed something. Please review. I get:
You're right - this won't work. You'll ALWAYS invoke the appropriate showMe()
for the object passed as the first argument of invoke(), regardless of which
ancestor class you got the Method from.
Good :)
--
Mark Rafn dagon@dagon.net <http://www.dagon.net/>
proudbug - 02 Jan 2008 17:04 GMT
> >This does not seem to work. However, to be fair, I was not really
> >expecting it to work so I may have missed something. Please review. I get:
[quoted text clipped - 7 lines]
> --
> Mark Rafn da...@dagon.net <http://www.dagon.net/>
To make it work, you just need to use "new A()" as the first argument
of invoke(), instead of "this".
Patricia Shanahan - 02 Jan 2008 17:14 GMT
>>> This does not seem to work. However, to be fair, I was not really
>>> expecting it to work so I may have missed something. Please review. I get:
[quoted text clipped - 9 lines]
> To make it work, you just need to use "new A()" as the first argument
> of invoke(), instead of "this".
It depends what you mean by "work". In this, extremely simple, situation
all instances of A do exactly the same thing on showMe() call.
In more realistic situations, a new A() would not necessarily produce
the behavior of the A showMe for the the C instance doing the call.
Patricia
proudbug - 03 Jan 2008 15:51 GMT
> >>> This does not seem to work. However, to be fair, I was not really
> >>> expecting it to work so I may have missed something. Please review. I get:
[quoted text clipped - 17 lines]
>
> Patricia- Hide quoted text -
I see your point. Thanks.
Kira Yamato - 02 Jan 2008 03:02 GMT
> [ B extends A, C extends B, each implements/overrides showMe() ]
>
[quoted text clipped - 5 lines]
> shouldn't know or care about it's implementation beyond what method signatures
> are available to you.
Good point. I'm just trying to readjust from the C++ mindset here.
> 2) If you really need it, you could use reflection.
> this.getClass().getSuperclass().getSuperclass().getMethod("showMe", null)
> will get you the Method you want to call.
I think the dynamic method lookup mechanism would still cause the
program to give me C's version of the method again.
Anyway, it was just an academic question. As you pointed out, a proper
object design should not require this need.
Thanks.

Signature
-kira
> class A
> {
[quoted text clipped - 7 lines]
>
> class C extends A
You mean "extends B" for the question to make sense.
> {
> public int showMe() { System.out.println("C"); }
[quoted text clipped - 5 lines]
>
> // Question: how can I access class A's showMe()?
You can't.
Perhaps using reflection, but that's sidestepping a restriction
that is there for a reason.
A more relevant question is: Why do you want to? Should you instead
change your model or class hierarchy so that it matches what you want
to do with it?
> // I'm suspecting this cannot be done without modifying codes
> outside of class C.
Correct.
/L

Signature
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Kira Yamato - 02 Jan 2008 02:59 GMT
>> class A
>> {
[quoted text clipped - 25 lines]
>
> A more relevant question is: Why do you want to?
I don't. It's just an academic question.
> Should you instead
> change your model or class hierarchy so that it matches what you want
> to do with it?
And you're right. In a proper design, I should've given these methods
different signature so that I can differentiate them in class C.
>> // I'm suspecting this cannot be done without modifying codes
>> outside of class C.
>
> Correct.
Thanks.

Signature
-kira
> // Question: how can I access class A's showMe()?
The short answer, as others have answered, you can't.
The longer, more esoteric answer:
The Java bytecode has two [*] means of calling non-static methods:
invokevirtual and invokespecial (or invokenonvirtual). The difference
between the two is in how the VM selects the method to invoke: the
virtual one starts its way from the "runtime class" and works up to find
the method, the latter from the "compile-time class" (not the most
precise terms).
When a method is called in Java, the compiler selects the virtual flavor
except in one of two circumstances:
1. The method is private.
2. The method is called using super.
In the latter case, only one super can appear (so super.super is not
possible). This means in practice that the only control one has in the
second case is to choose nonvirtual methods based on the immediate
superclass and not other ancestors, a limitation not present in the
bytecode.
In short: it's possible if you're directly writing the bytecode.
[*] There are five invoke opcodes: invokespecial, invokevirtual,
invokeinterface, invokestatic, and invokedynamic. The latter are
excluded because invokeinterface is essentially an invokevirtual,
invokestatic uses static methods which do not inherit, and invokedynamic
is an opcode for languages over than Java.

Signature
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
Kira Yamato - 03 Jan 2008 00:42 GMT
>> // Question: how can I access class A's showMe()?
>
[quoted text clipped - 25 lines]
> invokestatic uses static methods which do not inherit, and
> invokedynamic is an opcode for languages over than Java.
Thanks for the information on the inner workings of java. I have
subsequently found the java 3.0 spec. and am currently studying it.

Signature
-kira
Lew - 03 Jan 2008 06:10 GMT
> Thanks for the information on the inner workings of java. I have
> subsequently found the java 3.0 spec. and am currently studying it.
Do you mean /The Java Language Specification, Third Edition/,
<http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html>
?
There is no such thing as a "java 3.0 spec".

Signature
Lew
Kira Yamato - 03 Jan 2008 06:48 GMT
>> Thanks for the information on the inner workings of java. I have
>> subsequently found the java 3.0 spec. and am currently studying it.
>
> Do you mean /The Java Language Specification, Third Edition/,
> <http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html>
> ?
Yes, that's right. The java language specification, 3rd edition.

Signature
-kira