4

There is class T:

public class T
{
    protected String name;
    public T(String name)
    {
        this.name = name;
    }
    public String toString()
    {
        return "T:"+this.name;
    }
}

Class G:

public class G extends T
{
     public G(String name)
     {
          super(name);
     }
     public String toString()
     {
          return "G:" + super.toString();
     }
}

When I run

G a3 = new G("me");
System.out.println((T)a3)

It prints G:T:me.

I don't understand why. I thought it would print T:me. I claim this because it was casted as object T. And therefore, using the toString() of class T. However, I'm wrong. Why does this happen?

I know there are not good names for classes, it's a question about understanding polymorphism and inheritance, not just to write a specific code I need.

10
  • What does super.toString() do? Commented Apr 6, 2016 at 15:47
  • Are you asking me a question for you to understand or a question so I can think about it? With that code it will activate the method toString() of the class T. Commented Apr 6, 2016 at 15:49
  • So you would think about it. Commented Apr 6, 2016 at 15:50
  • @Pillar Oh so am I right? Commented Apr 6, 2016 at 15:51
  • The part I don't understand is why it doesn't activate the method of toString() on the class T. Commented Apr 6, 2016 at 15:52

3 Answers 3

4

The method toString() in class G overrides the method in class T, so it gets chosen. The static type of the object is used by the compiler to decide which overload of a method to use. It could only make a difference if there were two different toString() methods defined on T to choose from, and / or G defined another toString() overload somehow - although it's not really possible when there are no arguments to the method.

Sign up to request clarification or add additional context in comments.

Comments

3

The crucial point here is a cast does not change the object in any way. All it does is allow you to treat it as a different (compatible) type. The objects functionality stays exactly the same.

The code:

 public String toString()
 {
      return "G:" + super.toString();
 }

completely removes the old toString to a point where it is no longer accessable at all (mostly).

5 Comments

What do you mean treat it as a different compatible type?
@PichiWuana - compatible means you can cast up or down but you cannot cast across. E.g. You can cast any object up to (Object) or down to it's actual type but not across to something like Integer or HashMap.
If a4 is a T object, what would happen with System.out.println((G)a4);?
@PichiWuana - It will always call the method of the actual object it has, not the type it is pretending to be. In your case if a4 is a T then System.out.println((G)a4) will invoke T.toString() every time.
But can you cast it to T's son?
3

G a3 = new G("me");

This line calls both the construcotrs of T as well as G.

public T(String name)
{
    this.name = name;
    // so, this.name gets initialised to me.
}

public G(String name)
 {
      super(name);
 }

Now, since you have overridden the toString() method, but, calling the System.out.println((T)a3) doesn't change the type of a3 from Object to any other type. It makes possible printing a3 as an object(since println() also accepts parameter of type Object), but, a3 is still being overridden in both the classes.

So, your toString() method will be called, thereby leading to printing of G:T:me..

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.