【问题标题】:Solving upcasting/downcasting problems解决向上转换/向下转换问题
【发布时间】:2011-12-27 15:07:13
【问题描述】:

有没有人有任何可行的策略来解决转换/向上转换问题?我理解何时允许向上转换和向下转换,但是当问题往往涉及多个对象时,我往往很快就会感到困惑。例如,找到这样一个问题的答案的最佳方法是什么:

问题:编译以下程序的结果是什么:

interface Inter{}
class Base implements Inter{}
class Derived extends Base{}

class ZiggyTest2{

    public static void main(String[] args){

        Base b = new Base();
        Derived d = new Derived();
        Inter i = (Base)b;
        i = (Base)d;
        Derived bd = (Derived)b;
        b = (Base)i;        
    }   
}

我对答案并不感兴趣,但对解决问题的方法更感兴趣。有什么方法/策略可以用来解决上面的向上转换/向下转换问题吗?例如,是否可以将参考/对象绘制在纸上,以便我可以获得视觉表示,这有帮助吗?

谢谢

【问题讨论】:

    标签: java casting scjp ocpjp


    【解决方案1】:

    有一些简单的规则

    • 您可以转换为类前身(一直到 Object)(永远不会失败)
    • 您可以强制转换为子类 - 这可能会在运行时失败
    • 您可以从实现它的类转换为接口(永不失败)
    • 您可以从 interafce 转换为 iplemneting 类 - 这可能会在运行时失败

    前两条规则也适用于 ti 接口。

    您可以绘制UML class diagram 以将其可视化(仅使用 implements = implementations, extends realetions),沿箭头方向浏览图表将是安全的。以另一种方式导航将是运行时 usafe。并且在没有扩展/实现关系的情况下进行导航是不可能的。

    【讨论】:

    • 很好的答案。
    【解决方案2】:

    这是一个关于向上转换和向下转换的great article

    引自文章--

    首先,你必须明白,通过强制转换你实际上并没有改变对象本身,你只是给它贴上了不同的标签。

    问自己一个问题“对象的类型是什么?”然后记住,将其强制转换为类层次结构中的任何前驱类(包括接口)是合法的。

    在您的情况下,您正在创建 2 个对象,一个 BaseDerivedBase 可以标记为InterBaseDerived 可以标记为InterBaseDerived。因此,您的代码将编译得很好。但是在运行时,当你尝试将Base b 转换为Derived bd 时,你会得到一个ClassCastException。

    【讨论】:

      【解决方案3】:

      如果被操作的对象在同一层次中,强制转换肯定会编译,但它可能会在运行时失败。

      例如:

      class Animal { }
      class Dog extends Animal { }
      class Bulldog extends Dog { }
      

      如果你写:

      Animal animal = new Animal();
      Dog d = (Dog) animal;
      

      上面的代码可以编译,但在运行时会失败。因为编译器所能做的就是检查这两种类型是否在同一个继承树中。编译器允许可能在运行时工作的东西。但是如果编译器确定某些东西永远不会工作,它会在运行时本身抛出错误。例如

      Animal animal = new Animal();
      Dog d = (Dog) animal;
      String s = (String) animal;
      

      这肯定会失败,因为编译器知道 String 和 Dog 不在同一个层次结构中。

      同样的规则也适用于接口。

      希望对你有帮助。

      【讨论】:

        【解决方案4】:

        对我来说,我想先画出这些类型的层次结构。对于您的问题,类型的“级别”是:


        Inter(高于)

        Base(高于)

        Derived


        对象的“级别”在其创建时就已确定,对象只能“上升”而不能下降,具体取决于其创建级别。例如,对象b 被创建为Base 对象,因此它处于Base 的级别。你可以很容易地发现b可以向上转换为Inter,但不能向下转换为Derived,无论用什么类型来描述b。如果用Inter来描述b,由于它的创建级别是Base,可以向下转型为Base

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-19
          相关资源
          最近更新 更多