我有这段代码:
public abstract class animal {
public final static int elephent = 1;
public final static int dog = 2;
和两个子类:
public class elephant extends animal {
public final static int type = animal.elephent;
public elephant (String name){
super(name);
}
}
public class dog extends animal {
public final static int type = animal.dog;
public dog (String name){
super(name);
}
}
现在,说我有一个字母列表,上面有字母E-大象和D-狗。 和一个相同大小的动物类的空列表。 对于第一个列表中的每个字符,我想创建一个正确动物的新实例。 例如:[“d”,“e”,“d”] 会给我一个清单:[新狗,新大象,新狗] 希望我说清楚, 提前感谢您的帮助。
答案 0 :(得分:2)
这种设计不是最佳选择。您使用整数变量指示类型,这确实不是一个好主意。
第一项改进:将类型指示设为枚举。
public enum AnimalType {
ELEPHANT, DOG
}
现在在动物类中添加一个类型字段:
public abstract class Animal {
private final AnimalType type;
private final String name;
protected Animal(AnimalType type, String name) {
this.type = Objects.requireNonNull(type);
this.name = Objects.requireNonNull(name);
}
// more fields and methods here
}
大象看起来就像那样(狗很相似):
public class Elephant extends Animal {
public Elephant(String name) {
super(AnimalType.ELEPHANT, name);
}
// more fields and methods here
}
主要缺点:每次添加新动物类型时,都必须添加新类并在枚举中添加类型。这不是最好的设计。此外,实际上不需要类型枚举,因为子类型已经包含类型信息
班级Elephant
的一个实例是大象(狗一样)。它不需要类型字段。
第二项改进:完全删除类型指示。没有整数,没有枚举。只需要抽象类和子类。
现在您的问题是,如何从任何字符输入中获取正确的实例。这称为映射。你想映射
班级
Elephant
的字符“E”。班级
Dog
的字符“D”。
这可以通过Java Map
实现:
Map<Character, Class<? extends Animal>> charToAnimal = new HashMap<>();
charToAnimal.put('E', Elephant.class);
charToAnimal.put('D', Dog.class);
Class<? extends Animal> animalClass = charToAnimal.get('E');
String name = ...;
Animal animal = animalClass.getConstructor(String.class).newInstance(name); // will be an Elephant instance
此地图应该在您需要该行为的任何类中维护,或者如果您只是在学习如何操作,则可以在主方法中维护。
注意,我使用了一种名为reflection的Java机制,只是为了创建一个实例,因为没有其他通用的方法来处理实例化。
另一种方法是做同样的方法:
public Animal createAnimal(char c, String name) {
if (c == 'E') {
return new Elephant(name);
} else if (c == 'D') {
return new Dog(name);
} else {
throw new IllegalArgumentException(c);
}
}
无论哪种方式,你不仅要添加一个ne动物子类,而且你必须在地图中添加一个条目(见上文)或if方法的分支。
您可以使用枚举方法并将类实例化放入此枚举中。按照上面的动物类和以下类型枚举(未选中):
public enum AnimalType {
ELEPHANT('E', Elephant.class),
DOG('D', Dog.class);
private static final Map<Character, Class<? extends Animal>> CHAR_TO_ANIMAL = new HashMap<>();
AnimalType(char c, Class<? extends Animal> animalClass) {
CHAR_TO_ANIMAL.put(c, animalClass)
}
public Animal createAnimal(char c, String name) {
if (c == 'E') {
return new Elephant(name);
} else if (c == 'D') {
return new Dog(name);
} else {
throw new IllegalArgumentException(c);
}
}
}
答案 1 :(得分:1)
因此,您可能需要考虑的一件事是switch-case语句。所以在Java中,你可以这样做:
// get a char from the list.
char animal;
switch(animal)
{
case'e':
Elephant varName = new Elephant("Dumbo");
newList.add(varName);
break;
}
我没有在这里包含所有内容,但这应该让你开始。您需要通过数据结构查找迭代(循环)。
我会说实话,因为我写了任何Java已经有一段时间了,但这是你可以做到这一点的一种方式。还有其他方法可以做到这一点,例如使用if块。
希望这有帮助。
答案 2 :(得分:0)
我认为你需要的是一个静态工厂方法返回一个实例。这是一种方法。
抽象类:
public abstract class animal {
public final static char elephent = 'E';
public final static char dog = 'D';
}
大象班:
public class Elephant extends Animal {
private char myType;
private String name;
public Elephant(char type, String name) {
super();
this.myType = type;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getMyType() {
return myType;
}
public void setMyType(char myType) {
this.myType = myType;
}
}
狗类:
public class Dog extends Animal {
private char myType;
private String name;
public Dog(char type, String name) {
super();
this.myType = type;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getMyType() {
return myType;
}
public void setMyType(char myType) {
this.myType = myType;
}
}
工厂类:
public class FactoryMethod {
static char getAnimalIndex(char type){
switch (type) {
case 'E':
case 'e':
return Animal.ELEPHANT;
case 'D':
case 'd':
return Animal.DOG;
default:
throw new IllegalArgumentException(String.valueOf(type));
}
}
public static Animal getInstance(char type, String name){
Animal myCategory = null;
switch (getAnimalIndex(type)) {
case Animal.ELEPHANT:
myCategory = new Elephant(type,name);
break;
case Animal.DOG:
myCategory = new Dog(type,name);
break;
}
return myCategory;
}
}
用法:
如果你需要使用Animal类索引,或者你需要使用列表中的字符,这个工厂方法是有效的。 获取实例:
//using Animal index
FactoryMethod.getInstance(Animal.ELEPHANT,"Elephant");
FactoryMethod.getInstance(Animal.DOG,"Dog");
//using characters in list
FactoryMethod.getInstance('character_in_list_here',"Name OF The Animal Here");
由于它是静态方法,因此无需使用FactoryMethod实例即可使用。 我希望这就是你所需要的。