如何为通用类型创建工厂?

How do I create a Factory for a generic type?

我需要创建一个可以 return 具有特定参数化类型的对象的工厂对象。也就是说,我需要在工厂方法中指定对象的参数化类型。一个例子是我能想到的最好的解释方式,所以请考虑以下 class 定义。

interface Color {
    int getColor();
}

abstract class Animal<T extends Color> {
    T color;
    Animal(T col) { color = col; }
    public T getColor() { return color; }
}

class Dog<T extends Color> extends Animal<T> {
    public Dog(T col) {
        super(col);
    }
    public void woof() {
        System.out.println("Woof");
    }
}

class Cat<T extends Color> extends Animal<T> {
    public Cat(T col) {
        super(col);
    }
    public void meow() {
        System.out.println("Meow");
    }
}

class Blue implements Color {
    public int getColor() {
        return 1;
    }
    public void iAmBlue() {
        System.out.println("I am blue.");
    }
}

class Red implements Color {
    public int getColor() {
        return 2;
    }
}

// Expecting a base Factory interface that's something like this?
public interface Factory<K extends Animal<? extends Color>> {
    public <T extends Color> K create(T color);
}

public class CatFactory implements Factory<Cat<? extends Color>> {
    @Override // I want this to return Cat<T>, not Cat<?>
    public <T extends Color> Cat<? extends Color> create(T color) {
        return new Cat<T>(color);
    }
}

我基本上需要创建一个可以创建任何狗的工厂对象(Dog<Red>Dog<Blue>),以及一个可以创建任何猫的单独对象(Cat<Red>Cat<Blue>).构造对象时,我需要它能够 return Dog<Red>Dog<Blue>,而不是 Animal<?>Dog<?>。因此,像这样的东西应该是有效的(不需要类型转换):

dogFactory.create(new Red()).woof();
dogFactory.create(new Blue()).getColor().iAmBlue();

根据 dogFactory.create(new Blue()).getColor().iAmBlue(),我得出结论,您需要在工厂的某个地方保存 Color 类型 。由于 create() 方法是目前唯一拥有它的方法,因此您需要在 class 级别提取它的类型参数。类似于:

public interface Factory<T extends Color, K extends Animal<T>> {
    public K create();
}

这需要将工厂实现更改为:

public class CatFactory<T extends Color> implements Factory<T, Cat<T>> {

    private T color;

    public CatFactory(T color) {
        this.color = color;
    }

    @Override
    public Cat<T> create() {
        return new Cat<T>(color);
    }

    public T getColor() {
        return color;
    }

}

现在,您可以通过像这样实例化工厂来执行示例中需要的操作:

public static void main(String[] args) {
    CatFactory<Blue> blueCatsFactory = new CatFactory<Blue>(new Blue());
    blueCatsFactory.create().meow();
    blueCatsFactory.create().getColor().iAmBlue();
}