解决上行/下行问题

时间:2011-12-27 15:07:13

标签: java casting scjp ocpjp

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

  

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

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;        
    }   
}

我对答案并不感兴趣,但更多的是解决问题的方法。我可以使用任何方法/策略来解决上面的上行/下行问题吗?例如,可以在纸上绘制参考/对象,以便我可以获得视觉表示并且可以帮助吗?

由于

4 个答案:

答案 0 :(得分:3)

这是关于向上转发和向下转发的great article

引用文章 -

首先,你必须明白,通过投射你实际上并没有改变对象本身,你只是用不同的方式标记它。

问自己一个问题“对象的类型是什么?”然后记住将它转换为类heirarchy(包括接口)中的任何前任类是合法的。

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

答案 1 :(得分:2)

有一些简单的规则

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

前两个规则也适用于接口。

您可以绘制UML class diagram以使其可视化(仅使用implements = realizes,扩展重新定位),在箭头方向上导航将是安全的。导航另一种方式是运行时usafe。并且没有扩展/实现关系的导航是不可能的。

答案 2 :(得分:1)

如果正在操作的对象位于同一层次结构中,则会进行转换以确保编译,但在运行时可能会失败。

E.g:

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

如果你写:

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

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

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

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

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

希望它有所帮助。

答案 3 :(得分:1)

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


Inter(高于)

Base(高于)

Derived


对象的“级别”在其创建时确定,并且对象只能根据其创建级别“向上”而不是向下。例如,对象b被创建为Base对象,因此它处于Base级别。无论用什么类型描述b,您都可以轻松找到b可以向Inter转播,但不能向下转发到Derived。如果Inter用于描述b,由于其创建级别为Base,您可以将其向下转换为Base