java 帮助阐明泛型工厂方法 类

java Help clarifying Factory Methods with Generic Classes

老实说,我不确定这个标题是否合适;但我会尝试用例子来解释我的问题。

假设我有两个 类

public class Entity {
    private static int lastID = 0;
    private int ID;

    private Entity(){};

    public static Entity create(){
        lastID++;

        Entity ent = new Entity();
        ent.ID = lastID;

        return ent;
    }
}

public class Blob extends Entity {
    private int x,y;

    pubic void setPos(int X,int Y){;
        x = X;
        y = Y;
    }
}

我想与实体工厂交互的方式是

Blob b = Entity.create<Blob>();

或者那种性质的东西。

我最好的尝试是

public static <E extends Entity> E create(){
    E ent = new E();
    ...

但这行不通。

一个简单的工厂方法可能看起来像这样。将其保存在自己的 class 中(不在实体 class 中)并在名称中的某个位置使用名称 Factory,因此它具有上下文

public static final Entity getInstance(String id){
    Entity instance = null;
    if(id.equals("Blob")) {
        instance = new Blob();
    }
    else if(id.equals("Another Blob")) {
        instance = new AnotherBlob();
    }
    // more Entity types here
    return instance;
}

如果不实际传递 class 或其名称作为参数,恐怕无法完成。

然后您可以使用通用构造 <E extends Entity<E>> 使其类型安全并避免手动类型转换。

public class Entity<E extends Entity<E>> {
    private static int lastID = 0;
    protected int ID;

    protected Entity() {
    }

    public static <E extends Entity<E>> E create(Class<E> clazz) {
        lastID++;

        E newItem;
        try {
            newItem = clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e); // let's hope your child classes will have a working default constructor 
        }
        newItem.ID = lastID;
        return newItem;
    }

    public int getID() {
        return ID;
    }
}

public class Blob extends Entity<Blob> {
    private int x,y;

    public Blob() {
    }

    public void setPos(int X,int Y){;
        x = X;
        y = Y;
    }
}

public class AnotherBlob extends Entity<AnotherBlob> {

    String help = "Help!";

    public String help() {
        return help;
    }

}

// TEST!
public class Test {

    public static void main(String[] args) {
        Blob blob = Entity.create(Blob.class);
        AnotherBlob anotherBlob = Entity.create(AnotherBlob.class);

        System.out.println("Blob: " + blob.getClass() + " ID = " + blob.getID() +
                "\nAnother blob: " + anotherBlob.getClass() + " ID = " + anotherBlob.getID());
    }

}