views:

121

answers:

4

Let's say I have an animal and now I want to make it a dog. How do I go about doing this in java?

Right now I have a constructor that looks like

public Dog(Animal animal) {
  this.setProperty(animal.getProperty);
  ...
}

While this works, it's fragile. Any other suggestions?

A: 

Do you want to subclass the Animal class? You could also use:

public class Dog extends Animal { 
    public Dog () {
        super();
        // other constructor stuff
    }
}

Then your Dog object would already inherit properties.

ruquay
+5  A: 

If your Dog extends Animal, you can create a constructor that takes an Animal and initializes the super(parent) constructor:

public class Dog extends Animal {
    public Dog(Animal animal) {
        super(animal);
    }
}

Assuming you have an Animal class that has a copy constructor in this form:

public class Animal {
    public Animal(Animal animal) {
        // copies all properties from animal to this
    }
}

You can create a Dog from an Animal by doing something like this:

Dog newDog = new Dog(myExistingAnimal);
Kekoa
That's more or less the same solution I have now, except that the copy code is in the descendant. This does improve the design, but it still feels like there should be a better solution available.What about using reflection?
Preston
A: 

Try and use a factory. Rather than basing it on the constructor, use a factory to return a specific type of Animal based on whatever is your constraints.

A: 

I'm not sure precisely what you want, so I'm going to assume you want the Animal object upgraded in place to be a Dog object.

class AnimalImpl {
    // ...
}

class DogImpl extends AnimalImpl {
    // ...
}

class Animal {
    private AnimalImpl implementation;
    public Animal() {
        implementation = new AnimalImpl;
    }
    public void becomeADog() {
        implementation = new DogImpl(implementation);
    }
    // ...
}

Use it like this:

Animal animal = getAnAnimalFromSomewhere();
// `animal` has generic Animal behaviour
animal.becomeADog();
// `animal` now has Dog behaviour

This might not be what you want, but it can be useful when an object should have substantially different behaviour, depending on its state.

Dave Hinton