How to downcast a Java object?

nbarraille picture nbarraille · Oct 27, 2010 · Viewed 28.6k times · Source

I am trying to understand Java's polymorphism, and I have one question about downcasting an object. Let's say for this example I have two subclasses Dog and Cat that inherit from a superclass Animal

From what I understood, the only way to downcast an object is if this Object is already of the good type, like this:

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

This works right?

But what if I want to create a regular animal without knowing what it would be, and then cast it when I know, how can I do that?

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

This will throw a ClassCastException at runtime right?

The only way I found to do that is to create a new Dog constructor that creates a dog from a regular animal:

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

with

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

So my question is, how am I supposed to do this?

  • Am I doing it the best way?
  • Am I not supposed to do this at all, if I have to it means my program is not well conceived?
  • Is there a better way I missed?

Thanks a lot! nbarraille

Answer

Tom Hawtin - tackline picture Tom Hawtin - tackline · Oct 27, 2010

If you want to create an instance of a type that may vary depending upon non-local conditions, use an Abstract Factory (as described in the Design Patterns book).

In it's simplest form:

interface AnimalFactory {
    Animal createAnimal();
}

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

Note also there is a difference between the static type of a reference and the dynamic type of the object. Even though you have an Animal reference, if the original object is a Dog, it still behaves like a Dog.