【问题标题】:Casting between interfaces接口之间的转换
【发布时间】:2012-10-24 12:30:03
【问题描述】:

我的问题与 Java 语言有关。 这是我得到的:

interface I1{}
interface I2{}
class C1 implements I1{}
class C3 extends C1 implements I2{}

     C1 01;
     C3 o3;
     I1 i1;

现在证明I2 i2 = (I2) i1; 是正确的,因为在运行时 i1 实际上指的是实现 I2 的对象。 但我不明白。接口之间没有任何关系,那么如何将其转换为相邻的接口呢? 没有更多的代码,它只是为了准备Java认证的练习。 最好的问候

【问题讨论】:

  • 在您的代码中,即使接口之间没有任何直接关系,但它们之间确实通过实现它们的类之间存在关系。
  • i1 变量声明在哪里?
  • 请发布 i1 变量的声明。一个完整的代码片段会更有用。
  • @techfoobar 如果您尝试将 I1 类型的 expr 转换为 I2,则该关系无关紧要。运行时值类型不在此处输入等式。

标签: java interface casting


【解决方案1】:

如果您将Integer 转换为String,编译器可以将其视为非法而停止,但是,由于一个类可以实现多种接口,编译器无法知道您在转换时是否违规接口类型到另一个。考虑这段代码:

I1 i1 = getI1();
if (i1 instanceof I2) {
  I2 i2 = (I2) i1;
}

如果 Java 编译器不允许从一个接口转换到另一个接口,那么这段完全合法的代码将无法编译。

【讨论】:

    【解决方案2】:

    I2 i2 = (I2) i1;的意思是:我知道i1引用的对象的具体运行时类型实现了I2接口,所以我想把它引用为I2。如果i1 的具体运行时类型确实实现了I2,则转换将成功。

    I1I2 没有任何共同点这一事实并不重要。重要的是 i1 引用的对象的实际具体运行时类型。

    【讨论】:

      【解决方案3】:

      你自己回答了这个问题;-)

      "[... ]is right because at run time i1 actually refers to an object that implements I2"
      

      类型转换在运行时而不是在编译时进行评估。因此,如果i1 在运行时指向的对象是I2 类型,则没有错误。

      【讨论】:

        【解决方案4】:

        简单地说,接口是一种类型,就像鸟一样——不是鹰或鸭。 采取这些类的具体实现(这很愚蠢,但请耐心等待)

        interface Bird {fly();}
        interface Swimmer {swim();}
        class Eagle implements Bird {fly(){...};}
        class Duck extends Eagle implements Swimmer {swim(){...};}
        
        Swimmer i2 = (Swimmer) i1;
        

        这意味着您的代码认为 i1 是一个可以游泳的实体。如果 i1 是鸭子,此代码将起作用,如果它是鹰,则此代码将失败。类型转换是在运行时而不是编译时完成的。

        【讨论】:

        • 类也声明类型,而不仅仅是接口。
        • 是的 - 我试图过度简化(并在答案中加入游泳鸭)。这个问题似乎已经得到解答。
        猜你喜欢
        • 1970-01-01
        • 2012-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-05
        • 2011-02-08
        • 1970-01-01
        • 2021-06-08
        相关资源
        最近更新 更多