创建一个新的通用对象Java

时间:2011-02-22 07:01:58

标签: java generics

我正在尝试编写一组用于多个类的用户界面,它们都扩展了一个抽象类Category:HouseCategory extends Category,CarCategory extends Category

大多数代码只是通过使用多态来正常工作,但有一节我需要创建扩展类别的新实例

Obj foo = new HouseCategory(a, b, c)

如何让所有类别的子类都能正常工作? - 它们都具有相同的构造函数参数。我对泛型不太了解,但是我可以将UI类定义为

public class UserInterface <T extends Category> extends JFrame {

或可能

public class UserInterface  extends JFrame {
     public UserInterface(Class<T extends Category> clazz) {

从那里建造? 非常感谢。

编辑:另外,是否可以从泛型类中获取静态字段? 我宁愿不必检查“if(clazz instanceof HouseCategory)name = HouseCategory.NAME”,因为可能有数百个类。

3 个答案:

答案 0 :(得分:1)

由于类型擦除,泛型无法真正帮助您解决此问题。在运行时,您的代码不会“知道”类型参数的值。

一种方法是使用工厂模式。为每个类创建一个工厂类,并让它们都实现一个公共工厂接口(可能是CategoryFactory)。然后将工厂对象提供给UserInterface而不是Class对象。

另一种方法是使用反射来调用Class对象上的构造函数。我不喜欢这种方法,因为它会导致编译时检查窗口,但它会涉及在类上使用getConstructor方法。

答案 1 :(得分:1)

引入新的工厂以创建类别对象或用户界面。每当您添加新类别时,工厂都需要进行扩展,但这不应该是一个大问题:

public class CategoryFactory {
  public static enum Type {HOUSE, CAR}

  public static Category createCategory(Type type, Param a, Param 2, Param b) {
    if (type == null) return null;

    switch(Type) {
      case HOUSE: return new HouseCategory(a,b,c);
      case CAR: return new CarCategory(a,b,c);
    }
    return null; // or throw exception -> tells, that a new enum is not handled yet
  }
}

然后,如果你protect类别中的构造函数子类并将这些子类和工厂保存在一个包中,你可以很难绕过工厂。

答案 2 :(得分:0)

将类传递给界面。使用反射来调用构造函数并访问NAME字段。但是最好采用子类可以覆盖的实例方法:

/** subclass must have the default constructor */
abstract class Category
    abstract void init(a, b, c);
    abstract String name();

class HouseCategory extends Category
    void init(a, b, c){ ... }
    String name(){ return "House"; }

class UserInterface
    UserInterface(clazz)
         Category foo = (Category)clazz.newInstance();
         foo.init(a,b,c);
         String name = foo.name();