I'm working on an example of a Zoo that has several different types of Animal. The user enters commands such "add tiger" and then a Tiger is added to the Zoo.
In my command interpreter class I have some code like this:
String animalName...
Animal newAnimal;
if (animalName.equals("tiger"))
newAnimal = new Tiger();
else if (animalName.equals("elephant"))
newAnimal = new Elephant();
The problem here is that when a new kind of animal is added to the program, this piece of code must also be changed. I'd like to add new animals just by subclassing Animal without changing anything in the already existing classes.
The name given by the user in her command isn't necessarily identical to the class name of the animal (for example, "add Bengal tiger" would add a BengalTiger object).
If possible, I'd prefer to avoid using reflection.
This is the final code:
private static String getClassName(String name) {
char ch;
int i;
boolean upper = true;
StringBuilder s = new StringBuilder("animals.");
for (i=0; i<name.length(); i++) {
ch = name.charAt(i);
if (ch!=' ') {
if (upper)
s.append(Character.toUpperCase(ch));
else
s.append(Character.toLowerCase(ch));
upper = false;
} else
upper = true;
}
return s.toString();
}
@Override
public Animal addAnimal(String s) {
try {
Animal animal = (Animal)Class.forName(getClassName(s)).newInstance();
addAnimal(animal);
return animal;
} catch (InstantiationException e) {
throw new IllegalArgumentException("There are no animals called like this");
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("There are no animals called like this");
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("There are no animals called like this");
} catch (ClassCastException e) {
throw new IllegalArgumentException("There are no animals called like this");
}
}