Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2008

Tip: Looking for answers? Try searching our database.

Accessing grandparent's overridden methods.

Thread view: 
Kira Yamato - 01 Jan 2008 20:47 GMT
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.

Signature

-kira

Mark Rafn - 01 Jan 2008 23:18 GMT
[ 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

Lasse Reichstein Nielsen - 01 Jan 2008 23:35 GMT
> 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

Joshua Cranmer - 02 Jan 2008 23:39 GMT
>        // 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



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.