如何为通用类型创建工厂?
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();
}
我需要创建一个可以 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();
}