【问题标题】:How to downcast a Java object?如何向下转换 Java 对象?
【发布时间】:2011-05-01 07:01:50
【问题描述】:

我正在尝试理解 Java 的多态性,并且我有一个关于向下转换对象的问题。 假设对于这个例子,我有两个继承自超类 Animal 的子类 Dog 和 Cat

据我了解,向下转换对象的唯一方法是该对象已经是好的类型,如下所示:

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

【问题讨论】:

    标签: java oop inheritance downcast


    【解决方案1】:

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

    最简单的形式:

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

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

    【讨论】:

      【解决方案2】:

      您应该只转换为对象真正的类,因此如果您有一个扩展 AnimalDog,您可以将其转换为 Animal(因为它是一个),但您不应该转换AnimalDog 因为并非所有 Animals 都是 Dogs。 Dog 类很可能有 Animal 类未实现的额外字段,因此强制转换没有意义(您将这些值初始化为什么?)。

      【讨论】:

        【解决方案3】:

        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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-02-04
            • 2022-11-21
            • 1970-01-01
            • 2017-03-16
            • 1970-01-01
            • 2011-05-26
            • 1970-01-01
            • 2023-03-17
            相关资源
            最近更新 更多