在继承中转换一个对象,为什么会输出这个?

Casting an object in inheritance, why this output?

有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();
     }
}

当我运行

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

它打印 G:T:me.

我不明白为什么。我以为它会打印 T:me。我声称这是因为它被转换为对象 T。因此,使用 class T 的 toString()。但是,我错了。为什么会这样?

我知道classes没有好听的名字,是理解多态和继承的问题,不只是写一个我需要的具体代码。

这里的关键点是转换不会以任何方式改变对象。它所做的只是允许您将其视为不同的(兼容的)类型。对象功能保持 完全相同

代码:

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

完全删除旧的 toString 到根本无法访问(大部分)的程度。

G a3 = new G("me");

这一行调用了 T 和 G 的构造函数。

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

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

现在,由于您已经覆盖了 toString() 方法,但是 ,调用 System.out.println((T)a3) 不会' t 将 a3 的类型从 Object 更改为任何其他类型。它使得打印 a3 作为对象成为可能(因为 println() 也接受对象类型的参数),但是,a3 仍然在 类.

中被覆盖

因此,您的 toString() 方法将被调用,从而导致打印 G:T:me.

class G 中的方法 toString() 覆盖 class T 中的方法,因此它被选中。编译器使用对象的静态类型来决定使用哪个overload方法。只有在 T 上定义了两个 different toString() 方法可供选择,和/或 G 以某种方式定义了另一个 toString() 重载时,它才会有所不同——尽管它是当方法没有参数时,这是不可能的。