There are many ways to do this, assuming by breed you mean "create children of me."
Reflection
First is to use reflection. If you have a no-args constructor for your classes, this is as easy as calling Class.newInstance:
public Animal breed() {
try {
return (Animal) getClass().newInstance();
} catch (Exception ex) {
// TODO Log me
return null;
}
}
If you don't have a no-args constructor in all your subclasses, you'll have to have a uniform constructor across all your subclasses. For example, if you have Cat(int, String) and Dog(int, String), then you need to get the constructor via Class.getConstructor and invoke newInstance on that:
return (Animal) getClass().getConstructor(int.class, String.class).newInstance(0, "Unnamed");
int and String here may be age and name, for example. This is how you do this with reflection.
Providers
Another way is to use this simple interface:
public interface Provider<T> {
T create();
}
Then have your abstract class take an instance of this in its constructor:
public abstract class Animal {
private final Provider<Animal> animalProvider;
protected Animal( ... , Provider<Animal> animalProvider) {
// ...
this.animalProvider = animalProvider;
}
public Animal breed() {
return animalProvider.create();
}
}
Then your subclasses will pass a Provider<Animal> to the superclass which will create new instances of the subclass:
public class Dog extends Animal {
public Dog( ... ) {
super( ... , new DogProvider());
// ...
}
private static class DogProvider implements Provider<Animal> {
public Animal create() {
return new Dog( ... );
}
}
}
Do the same for other subclasses as well.
Note: if by breed you mean "get the type of me," then you should edit your question to say so. If this is what you meant, then this is a viable solution:
public abstract class Animal {
protected final Breed breed;
protected Animal( ... , Breed breed) {
// ...
this.breed = breed;
}
public Breed getBreed() {
return breed;
}
}
I recommend following the get/set conventions for data container methods. Java has bean classes designed to handle these naming conventions, and it's more or less a standard across many platforms. For your subclasses:
public class Dog extends Animal {
public Dog( ... ) {
super( ... , new Breed( ... ));
// ...
}
}