【问题标题】:Couple java questions regarding type casting and inheritance关于类型转换和继承的几个java问题
【发布时间】:2014-04-22 18:41:39
【问题描述】:

您好,我有几个关于类型转换和继承的问题。我一直在做一些阅读,我了解类型转换的要点和基础知识。但是,我不完全了解我可以在哪里使用它,不能在哪里使用它。

考虑这个类:

class A{

        public A(){}            

}

A temp = new A();

temp = (Object)temp;

此代码给我错误“无法从类型 Object 转换为类型 A”。但是,这不是从 A 类型转换为 Object 类型吗?你能不输入层次结构吗?

现在我的第二个问题是关于继承等。

当你输入时:

Object temp = new A();

到底发生了什么? temp 是 A 还是 Object?

【问题讨论】:

  • @fge 是吗?它只是创建一个空的构造函数
  • 糟糕,我弄错了...但是; 是多余的
  • @appman0724 它是A。您将使用 A 的实例变量和方法
  • @fge 哦,是的;没必要谢谢
  • @mangusta 为什么要我在使用 A 的实例方法之前将其强制转换为类型 A?

标签: java inheritance casting


【解决方案1】:
A a = (Object)temp;

“无法从类型 Object 转换为类型 A”。但是,这不是从 A 类型转换为 Object 类型吗?你不能把类型向上转换吗?

你说得对

(Object)temp;

正在将temp(即A)转换为Object。然而,这不是编译器所抱怨的。现在你已经有效地,

A a = anObjectNOTAnA

A = ... 是无效代码。我已将其更改为A a = ...。)

这是说你不能将 Object 转换回 A,除非你明确地转换它并可能抑制 unchecked-cast 警告:

A a = (A)anObjectNOTAnA

@SuppressWarnings("unchecked")
A a = (A)anObjectNOTAnA

关于你的其他问题:

Object temp = new A();

到底发生了什么? temp 是 A 还是 Object?

当您转换任何类型的对象时,它永远不会更改底层对象的实际类型。 new A() 始终是 A,无论它是

A a = new A();

Object objButReallyA = new A();

@SuppressWarnings("unchecked")
A a = (A)((Object)new A());

如果A 存储在Object 中,则它只是同一对象的不同“视图”。但是,为了使用 A 的特定功能,您必须先将其恢复为 A 视图:

 objButReallyA.getAOnlyField();  //compile error

 ((A)objButReallyA).getAOnlyField();  //Okay

【讨论】:

    【解决方案2】:

    问题出在最后一行。首先,您通过以下语句向 Java 保证 temp 是 Object 类型:

    (Object) temp
    

    之后,您尝试将编译器认为是 Object 类型的对象分配给应该是 A 类型的变量。因此,总而言之,将 temp 转换为 Object 类型的部分很好,问题是当您之后尝试将其分配给期望 A 类型的变量。

    对于第二个问题,temp 是 A。使用 new 关键字创建对象时,对象的类型将始终是紧随其后的类型。在您的情况下 A. 然后将 temp 分配给 Object 类型的变量,但这不会改变 temp 的实际类型。拥有某种 X 类型的变量只会告诉您该变量指向的任何内容都是 X 的子类型。

    【讨论】:

      【解决方案3】:

      这只是因为您不能将超类对象分配给子类引用。

      所以你不能这样做:

      temp = (Object)temp;
      

      因为它与:

      Object newObject = new Object();
      A temp = newObject;
      

      你会在这里得到同样的编译错误。

      当然你可以这样做:

      Object newObject = new Object;
      A temp = new A();
      newObject = temp;
      

      您可以这样做,因为您可以将子类分配给超类引用

      【讨论】:

        【解决方案4】:

        这里是JLS 8.1.3的摘录:

        如果类声明为任何其他 类没有扩展子句,那么 类具有类Object 作为其 隐式直接超类。

        当然,Object 本身就有点特别(JLS):

        除了Object 之外的每个类都是一个 扩展(即,子类) 一个现有的类(§8.1.3)和 可以实现接口(第 8.1.4 节)。

        每个类都是Object 的后代。

        在您的情况下,您尝试将 A 的对象存储到名为 A 的 Class 对象中。这是行不通的。你需要做的:

        Object testObject = (Object)temp;

        这会将Object 存储到testObject 中,它的类型为您所转换的Object

        这里是working on ideone

        【讨论】:

          猜你喜欢
          • 2014-12-16
          • 1970-01-01
          • 1970-01-01
          • 2011-08-01
          • 2013-10-16
          • 1970-01-01
          • 2011-03-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多