如何向下转换Java对象?

时间:2010-10-27 12:26:36

标签: java oop inheritance downcast

我正在尝试理解Java的多态性,我有一个关于向下转换对象的问题。 让我们说这个例子我有两个继承自超类Animal

的子类Dog和Cat

根据我的理解,向下转换对象的唯一方法是,如果此Object已经是好的类型,如下所示:

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

这适用吗?

但是如果我想在不知道它会是什么的情况下创造一只普通的动物,然后在我知道的时候施放它,我该怎么办呢?

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

这会在运行时抛出ClassCastException吗?

我发现这样做的唯一方法是创建一个新的Dog构造函数,从常规动物创建一条狗:

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

public Class Dog extends Animal{
   public Dog(Animal a){
      super(a);
   }
}

所以我的问题是,我该怎么做呢?

  • 我这样做是最好的方式吗?
  • 我根本不应该这样做,如果我必须这样做意味着我的节目没有很好地构思出来?
  • 我错过了更好的方式吗?

非常感谢! nbarraille

4 个答案:

答案 0 :(得分:9)

如果要创建可能因非本地条件而异的类型实例,请使用Abstract Factory(如“设计模式”一书中所述)。

以最简单的形式:

interface AnimalFactory {
    Animal createAnimal();
}

class DogFactory implements AnimalFactory {
    public Dog createAnimal() {
        return new Dog();
    }
}

另请注意,引用的静态类型与对象的动态类型之间存在差异。即使您有Animal引用,如果原始对象是Dog,它仍然表现得像Dog

答案 1 :(得分:3)

您应该只转换为该对象确实存在的类,因此,如果您有Dog扩展Animal,则可以将其转换为Animal(因为它是一个)但是您不应该将Animal投射到Dog,因为并非所有Animal都是DogDog类可能有额外的字段没有Animal类实现,所以演员表没有意义(你将这些值初始化为什么?)。

答案 2 :(得分:1)

Java是一种强类型语言,这意味着您只能将对象转换为它所扩展的类型(超类或接口)。

即使你“假装”,例如复制所有类方法和字段,你只是不能将对象强制转换为它不扩展的类型。

public class Foo{

    public String phleem;

    public void bar(){

    }

}

public class Bar{

    public String phleem;

}

public interface Baz{

    public void bar();

}

鉴于上述代码,您无法将Foo对象转换为BarBaz,尽管类结构似乎暗示您可以。没有涉及继承,因此抛出ClassCastException

答案 3 :(得分:0)

这里你谈论的是向下转换,所以在这种情况下,总是应该使用超类作为引用,并且应该指向子对象。 这个usd基本上是工厂模式。

相关问题