【问题标题】:Difference between downcasting Class vs downcasting Interface in Java?Java中向下转换类与向下转换接口之间的区别?
【发布时间】:2016-02-05 08:05:23
【问题描述】:

为什么我们可以像这样从超类转换为子类:

Object o = getStringObject();
String str = (String) o;

但随后使用相同的原理将接口 DOWN 转换为子类型 E.G.?

InterfaceType anInterface;
anInterface = (InterfaceType) SubClassVar;

所以示例 1 一切都很好。我不明白的是,如果接口是实现它的类的超类型,那么当我们将类向下转换为接口时,如果在层次结构中接口更高,我们怎么没有 ClassCastException?我在某处读到,通过类和接口进行强制转换之间存在差异,但他们当然不想解释原因,所以我一直处于开放状态。谢谢,堆栈!

【问题讨论】:

  • 我很困惑。你是说SubClassVarInterfaceType 吗?那么演员阵容就没用了。
  • @SotiriosDelimanolis SubClassVar 是一个实现 InterfaceType 的类
  • @SotiriosDelimanolis 也许我需要更多信息,但如果你是为 android 开发的,这是通信器模式,用于在活动和片段之间进行对话。
  • 第二个 sn-p 不需要演员表。

标签: java android interface casting


【解决方案1】:

当程序员显式地将一种类型转换为另一种类型时,通常是因为程序员比编译器更了解对象的运行时类型。编译器可以选择允许任何转换,因为聪明的程序员会这么说。但是,作为 Java,编译器会尝试捕捉和防止明显的错误。

如果很明显没有对象可以同时属于这两种类型,则不允许在两种类型之间进行强制转换;或者换句话说,这两种类型的交集是空的。例如,我们不能在StringInteger 之间进行转换;也不是StringRunnable。但是,NumberRunnable 可以相互转换,因为可以想象这两种类型都可能存在一个对象。

此外,身份比较 a==b 仅允许在 A 和 B 可以相互转换的情况下,出于相同的理由。如果编译器知道它们不能是同一个对象,则不允许==。见JLS

确切的算法非常复杂 - http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.5.1 注意算法是对称的 - A 可以转换为 B,当且仅当 B 可以转换为 A。规范的文本不是很好,可能包含错误(见question

“向下转型”是指目标类型是子类型; “向上转型”是当目标类型是超类型时。向上转换通常是不必要的,但在需要时有cases

【讨论】:

    【解决方案2】:

    从技术上讲,您向上转换为接口,因为它在层次结构中高于(假定?)该接口的实现者SubClassVar。此外,甚至不需要强制转换,因为无论如何都可以根据该接口来讨论接口的实现,而无需强制转换语法。

    可以像处理子类一样向下转换接口。这是一个例子:

    interface I1 {}
    interface I2 extends I1 {}
    
    class I2Impl implements I2 {}
    
    class Main {
       public static void main(String[] args) {
          I1 test = new I2Impl();
          I2 test2 = (I2)test;
          I2Impl test3 = (I2Impl) test2;
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-17
      • 2021-11-08
      • 1970-01-01
      • 2017-03-16
      • 2014-12-31
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多