如果我有一个标准枚举(在本例中是建筑物清单的表示),例如:
public enum BuildingType {
farm, shop, house
}
和一个基于“构建”超类创建对象的函数,例如:
public void addBuilding(BuildingType bType) {
Building b = new Building();
b.start();
}
我的所有子类都具有与BuildingType枚举相匹配的名称。 有没有一种方法可以使用我的枚举参数来设置对象b的类而不使用类语句?
显然不正确,但是像这样
Building b = new bType(); //using the argument
一如既往地谢谢。
答案 0 :(得分:2)
您可以定义一个同样为factory的枚举:
public enum BuildingType {
farm(Farm.class),
shop(Shop.class),
house(House.class);
private Class<? extends Building> clazz;
private BuildingType(Class<? extends Building> clazz) {
this.clazz = clazz;
}
public Building createBuilding() {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(clazz + " has no default constructor");
}
}
}
或稍微多一些代码,但避免反射,使枚举类成为abstract factory并让实例成为工厂:
public enum BuildingType {
farm() {
public Building createBuilding() {
return new Farm();
}
},
shop() {
public Building createBuilding() {
return new Shop();
}
},
house() {
public Building createBuilding() {
return new House();
}
};
public abstract Building createBuilding();
}
无论哪种方式,使用:
public void addBuilding(BuildingType bType) {
Building b = bType.createBuilding();
b.start();
}
答案 1 :(得分:0)
如果建筑物的不同行为将在类层次结构而不是枚举文字中表示,那么这将是一种更合适的方式 - 即,具有建筑物抽象基类的FarmBuilding,ShopBuilding和HouseBuilding子类建筑物的具体行为。
答案 2 :(得分:0)
您可以创建一个参数,声明每个枚举引用的类类型。它看起来像这样:
// Enums should be all caps btw
public enum BuildingType {
FARM(Farm.class), SHOP(Shop.class), HOUSE(House.class);
private Class<? extends Building> type;
private BuildingType(Class<? extends Building> type) {
this.type = type;
}
public Class<? extends Building> getType() {
return type;
}
}
然后,您可以在需要时创建该类的新实例。
Building myBuilding = BuildingType.FARM.getType().newInstance();
此示例假设您的类具有默认的无参数构造函数,因此请注意。
答案 3 :(得分:0)
我建议您阅读有关设计模式的信息,特别是有关工厂模式的信息。这是一个wiki链接http://en.wikipedia.org/wiki/Software_design_pattern,但你可以在互联网上找到大量的例子。 例如
BuildingFactory bf = BuildingFactory.newInstance();
Building b = bf.createBuilding(bType);
并在createBuilding方法中:
// return Building superclass which you can cast to specific type
public Building createBuilding(BuildingType bType) {
if(bType == something) {
return new FarmBuilding();
}
else if(...) {
return something else;
}
}
答案 4 :(得分:0)
像上面的某些答案一样,您可以使用抽象方法在Enums上实现它们。与许多人说的不同,您可以使用反射来实例化带参数的对象,如下所示:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="myform" autocomplete="off" method="post">
<fieldset>
<input class="class_x" type="radio" name="name_x" value="value_1" />
<input class="class_x" type="radio" name="name_x" value="value_2" />
<input class="class_x" type="radio" name="name_x" value="value_3" />
</fieldset>
<fieldset>
<input class="class_y" type="radio" name="name_y" value="value_1" />
<input class="class_y" type="radio" name="name_y" value="value_2" />
<input class="class_y" type="radio" name="name_y" value="value_3" />
</fieldset>
<fieldset>
<input class="class_z" type="radio" name="name_z" value="value_1" />
<input class="class_z" type="radio" name="name_z" value="value_2" />
<input class="class_z" type="radio" name="name_z" value="value_3" />
</fieldset>
<input type="submit" name="name_submit" value="OK" class="class_submit" id="SubmitButton" required/>
</form>
有关反思的更多信息,我建议您阅读O&#39; reilly:http://chimera.labs.oreilly.com/books/1234000001805/ch07.html#learnjava3-CHP-7-SECT-2
对于Bohemian:对于惯例,Java Enums应该是Upercase,如果你在Enums中没有参数,你可以删除括号。
我希望我有所帮助。
祝你有个愉快的一天。 :)