从枚举引用创建对象

时间:2014-02-16 13:21:43

标签: java enums

如果我有一个标准枚举(在本例中是建筑物清单的表示),例如:

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

一如既往地谢谢。

5 个答案:

答案 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中没有参数,你可以删除括号。

我希望我有所帮助。

祝你有个愉快的一天。 :)

相关问题