我正在研究一个具有几种不同类型动物的动物园的示例。用户输入命令“添加老虎”,然后将老虎添加到动物园。

在我的命令解释器类中,我有一些类似以下的代码:

String animalName...
Animal newAnimal;
if (animalName.equals("tiger"))
    newAnimal = new Tiger();
else if (animalName.equals("elephant"))
    newAnimal = new Elephant();


这里的问题是,当将一种新的动物添加到程序中时,也必须更改这段代码。我只想通过子类化Animal来添加新动物,而无需更改现有类中的任何东西。

用户在其命令中给定的名称不一定与动物的类名相同(例如,“添加孟加拉虎”将添加一个孟加拉虎对象)。

如果可能的话,我宁愿避免使用反射。



这是最终代码:

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");
    }
}

最佳答案

您应该使用动态类加载:Class.forName(name),例如:

String animal = ... // e.g. elephant
String className = "com.mycompany.animals." + animal.substring(0, 1).toUpperCase() + animal.subString(1);
Animal obj = (Animal)Class.forName(className);

09-25 19:55