代码之家  ›  专栏  ›  技术社区  ›  nbarraille

如何向下转换Java对象?

  •  19
  • nbarraille  · 技术社区  · 14 年前

    我试图理解Java的多态性,我有一个关于向下转换对象的问题。

    据我所知,向下转换一个对象的唯一方法是,如果这个对象已经是好的类型,比如:

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

    这样行吗?

    但是如果我想创造一个普通的动物却不知道它会是什么,然后在我知道的时候把它扔出去,我怎么能做到呢?

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

    这将在运行时抛出ClassCastException,对吗?

    我找到的唯一方法是创建一个新的狗构造函数,它可以从普通动物创建狗:

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

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

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

    • 我是不是做得最好?
    • 我不应该这么做吗?如果我必须这么做,那就意味着我的程序设计得不好?
    • 有没有更好的方法让我错过?

    谢谢!

    4 回复  |  直到 14 年前
        1
  •  9
  •   Stéphane Bruckert jungledev    11 年前

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

    最简单的形式是:

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

    注意引用的静态类型和对象的动态类型之间也有区别。即使你有一个 Animal 如果原始对象是 Dog ,它的行为仍然像 .

        2
  •  3
  •   Jackson Pope    14 年前

    Dog 延伸的 Animal 你可以把它投给 (因为它是一个)但是你不应该 动物 动物 s是 s、 那个 类,因此转换没有意义(将这些值初始化为什么?)。

        3
  •  1
  •   Sean Patrick Floyd    14 年前

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

    即使你“伪造”,例如复制所有的a类方法和字段,你也不能把一个对象转换成一个它没有扩展的类型。

    public class Foo{
    
        public String phleem;
    
        public void bar(){
    
        }
    
    }
    
    public class Bar{
    
        public String phleem;
    
    }
    
    public interface Baz{
    
        public void bar();
    
    }
    

    Foo 反对 Bar 或者 Baz ClassCastException 被扔了。

        4
  •  0
  •   Arun Pandeu    14 年前

    这美元基本上在工厂模式。