Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Accessing grandparent's overridden methods.

Reply
Thread Tools

Accessing grandparent's overridden methods.

 
 
Kira Yamato
Guest
Posts: n/a
 
      01-01-2008
class A
{
public int showMe() { System.out.println("A"); }
}

class B extends A
{
public int showMe() { System.out.println("B"); }
}

class C extends A
{
public int showMe() { System.out.println("C"); }

public void test()
{
showMe(); // prints C
super.showMe(); // prints B

// Question: how can I access class A's showMe()?
// I'm suspecting this cannot be done without modifying codes
outside of class C.
}
}

Thanks.

--

-kira

 
Reply With Quote
 
 
 
 
Mark Rafn
Guest
Posts: n/a
 
      01-01-2008
[ B extends A, C extends B, each implements/overrides showMe() ]

Kira Yamato <(E-Mail Removed)> wrote:
> 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().ge tMethod("showMe", null)
will get you the Method you want to call.
--
Mark Rafn http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.dagon.net/>
 
Reply With Quote
 
 
 
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      01-01-2008
Kira Yamato <(E-Mail Removed)> writes:

> class A
> {
> public int showMe() { System.out.println("A"); }
> }
>
> class B extends A
> {
> public int showMe() { System.out.println("B"); }
> }
>
> class C extends A


You mean "extends B" for the question to make sense.

> {
> public int showMe() { System.out.println("C"); }
>
> public void test()
> {
> showMe(); // prints C
> super.showMe(); // prints B
>
> // 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
--
Lasse Reichstein Nielsen - (E-Mail Removed)
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      01-02-2008
Mark Rafn wrote:
> [ B extends A, C extends B, each implements/overrides showMe() ]
>
> Kira Yamato <(E-Mail Removed)> wrote:
>> 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.


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().ge tMethod("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]);
}
}

}

 
Reply With Quote
 
Kira Yamato
Guest
Posts: n/a
 
      01-02-2008
On 2008-01-01 18:35:43 -0500, Lasse Reichstein Nielsen <(E-Mail Removed)> said:

> Kira Yamato <(E-Mail Removed)> writes:
>
>> class A
>> {
>> public int showMe() { System.out.println("A"); }
>> }
>>
>> class B extends A
>> {
>> public int showMe() { System.out.println("B"); }
>> }
>>
>> class C extends A

>
> You mean "extends B" for the question to make sense.
>
>> {
>> public int showMe() { System.out.println("C"); }
>>
>> public void test()
>> {
>> showMe(); // prints C
>> super.showMe(); // prints B
>>
>> // 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?


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.

--

-kira

 
Reply With Quote
 
Kira Yamato
Guest
Posts: n/a
 
      01-02-2008
On 2008-01-01 18:18:09 -0500, (E-Mail Removed) (Mark Rafn) said:

> [ B extends A, C extends B, each implements/overrides showMe() ]
>
> Kira Yamato <(E-Mail Removed)> wrote:
>> 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.


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().ge tMethod("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.

--

-kira

 
Reply With Quote
 
Mark Rafn
Guest
Posts: n/a
 
      01-02-2008
Patricia Shanahan <(E-Mail Removed)> wrote:
>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 (E-Mail Removed) <http://www.dagon.net/>
 
Reply With Quote
 
proudbug
Guest
Posts: n/a
 
      01-02-2008
On Jan 1, 11:18*pm, (E-Mail Removed) (Mark Rafn) wrote:
> Patricia Shanahan *<(E-Mail Removed)> wrote:
>
> >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 * *(E-Mail Removed) * *<http://www.dagon.net/> *


To make it work, you just need to use "new A()" as the first argument
of invoke(), instead of "this".
 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      01-02-2008
proudbug wrote:
> On Jan 1, 11:18 pm, (E-Mail Removed) (Mark Rafn) wrote:
>> Patricia Shanahan <(E-Mail Removed)> wrote:
>>
>>> 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 (E-Mail Removed) <http://www.dagon.net/>

>
> 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
 
Reply With Quote
 
Joshua Cranmer
Guest
Posts: n/a
 
      01-02-2008
Kira Yamato wrote:
> // 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.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Accessing overridden __builtin__s? garyjefferson123@yahoo.com Python 7 03-14-2006 05:26 PM
Datagrid CssClass being overridden by TD style Laurence Neville ASP .Net 4 09-23-2004 09:59 AM
accessing overridden methods Bryan Ray Javascript 1 12-06-2003 02:27 PM
Calling parent's method even though it has been overridden in the child Patel Java 6 10-23-2003 03:08 PM
Calling parent's method even though it has been overridden in the child Patel Java 1 10-23-2003 04:35 AM



Advertisments