【问题标题】:Casting an object in inheritance, why this output?在继承中强制转换对象,为什么会这样输出?
【发布时间】:2016-07-27 03:31:39
【问题描述】:

有T类:

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

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。因此,使用 T 类的toString()。但是,我错了。为什么会这样?

我知道类没有好名字,这是一个关于理解多态性和继承的问题,而不仅仅是编写我需要的特定代码。

【问题讨论】:

  • super.toString() 是做什么的?
  • 你问我的问题是为了让你理解还是让我思考一下?使用该代码,它将激活类 T 的 toString() 方法。
  • 所以你会考虑的。
  • @Pillar 哦,我说得对吗?
  • 我不明白的部分是为什么它没有激活类T上的toString()方法。

标签: java inheritance casting polymorphism output


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    G a3 = new G("我");

    这条线调用了 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) 不会将 a3 的类型从 Object 更改为任何其他类型.它可以将a3 打印为对象(因为 println() 也接受 Object 类型的参数),但是,a3 在两个类中仍然被覆盖。

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

    【讨论】:

      【解决方案3】:

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

      代码:

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

      将旧的toString 完全删除,使其完全无法访问(大部分情况下)。

      【讨论】:

      • 将其视为不同的兼容类型是什么意思?
      • @PichiWuana - 兼容意味着您可以向上或向下投射,但不能跨越。例如。您可以将任何对象投射到(Object) 或降低到它的实际类型,但不能投射到IntegerHashMap 之类的东西。
      • 如果a4 是一个T 对象,那么System.out.println((G)a4); 会发生什么?
      • @PichiWuana - 它会总是调用它拥有的实际对象的方法,而不是它假装的类型。在您的情况下,如果a4T,那么System.out.println((G)a4) 每次都会调用T.toString()
      • 但是你能把它投给T的儿子吗?
      猜你喜欢
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多