15

existantial question

if i have a class hierarchy like:

public class TestSuper {
    public static class A {
        @Override
        public String toString() { return "I am A"; }
    }
    public static class B extends A {
        @Override
        public String toString() { return "I am B"; }
    }
    public static void main(String[] args) {
        Object o = new B();
        System.out.println( o ); // --> I am B
        // ?????? // --> I am A 
    }
}    

From the main method, is it possible to call the toString of A when the instance is of type B ???

of course, something like o.super.toString() doesn't compile ...

fedevo
  • 631
  • 1
  • 7
  • 15

5 Answers5

27

You can't, and very deliberately so: it would break encapsulation.

Suppose you had a class which used a method to validate input by some business rules, and then call the superclass method. If the caller could just ignore the override, it would make the class pretty much pointless.

If you find yourself needing to do this, revisit your design.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    ok ok i know that, but in my case, i try to test something and in this test i want to print the object.tostring to have the instance address ... so ... it was a really an existantial question on java – fedevo Jun 17 '11 at 13:30
  • 1
    @federevo then your actual question has nothing to do with calling a superclass's method, you just want to get the object's address in memory. Have you heard of the [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? – Matt Ball Jun 17 '11 at 13:34
  • 2
    To get the instance address in memory (I guess you mean the Object's hashCode) you can call System.identityHashCode() on an object which overrides the hashCode() method and get what you want. (For debugging purpose only I guess) – cquezel Jun 06 '14 at 10:59
  • 1
    What makes you think that the instance address in memory is the hash code? (Bear in mind that the identity hash code has to stay stable, whereas the object can be moved around in memory...) – Jon Skeet Jun 06 '14 at 11:00
  • @JonSkeet obviously the instance address is not the hash code and nothing makes me think that nor have I implied that it was. I was refering to federevo's comment above "i want to print the object.tostring to have the instance address" – cquezel Jun 06 '14 at 11:06
  • 1
    @cquezel: You said: "To get the instance address in memory (I guess you mean the Object's hashCode) you can call System.identityHashCode()" - that suggests to me that you believe that calling `System.identityHashCode()` will return the instance address on memory. Maybe you just didn't express yourself clearly. – Jon Skeet Jun 06 '14 at 11:48
9

You can just add another method to call the super string. Something like:

public string getSuperString(){
    return super.toString();
}
mrK
  • 2,208
  • 4
  • 32
  • 46
  • 3
    yeah, Being able to do this would directly break encapsulation which is a fundamental idea of Java. Java doesn't like you to be able to access objects up the hierarchy unless you are supposed to. You can either use a method like this or rethink your design. – mrK Jun 17 '11 at 13:33
  • It's not my design - I'm having to work around a poorly designed library, and there are no alternatives :-/ – Jxtps Dec 30 '20 at 22:52
6

You can either

  • Add a method to A or B which you call instead.

     // to A
     public String AtoString() {
         return toString();
     }
     // OR to B
     public String AtoString() {
         return super.toString();
     }
    
  • Inline the code of A.toString() to where it is "called"

     // inlined A.toString()
     String ret = "I am A";
     System.out.println( ret );
    

Both these options suggest a poor design in your classes, however sometimes you have existing classes you can only change in limited ways.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
2

It's not possible, because toString() of A is overriden by B (I guess, you meant "class B extends A").

weekens
  • 8,064
  • 6
  • 45
  • 62
-1

In your code it is not possible, in case B extends A

public class TestSuper {
    public static class A {
        @Override
        public String toString() { return "I am A"; }
    }
    public static class B {
        @Override
        public String toString() { return "I am B"; }
    }
    public static void main(String[] args) {
        B b = new B();
        System.out.println( b ); // --> I am B
        A a = (A)b;
        System.out.println( a ); 
    }
} 
RamonBoza
  • 8,898
  • 6
  • 36
  • 48