我有一个接口来描述类何时可以创建其自身的“下一个”版本:
public interface Prototypeable<Type extends Prototypeable<Type>> {
public Type basePrototype(); // the zeroth raw instance of Type
public Type nextPrototype(); // the next instance of Type
}
用于
public class Prototyper {
public static <Type extends Prototypeable<Type>> List<Type> prototypeFactor(int numberOfInstances, Type proto) {
List<Type> result = new ArrayList<Type>(numberOfInstances);
Type holder = proto.basePrototype();
result.add(holder);
for (int i=1; i<numberOfInstances;i++) result.add(holder = holder.nextPrototype());
return result;
}
现在,我有一个基类
A implements Prototypeable<A>
和一个子类AButMore extends A
。我想拥有AButMore extends A implements Prototypeable<AButMore>
,但是这是不允许的(无法使用不同的类多次实现通用接口)。还要注意,A
和AButMore
都实现了其他一些接口,并且从A
到AButMore
的实现是相同的。有关解决此问题的建议?我似乎无法解决通用问题,因此我考虑了一些替代设计:
伪装饰这两个类-即,具有不实现
Prototypeable
接口的基类,从该基类继承到适当的子类,然后将这两个类扩展到它们自己的可原型版本。缺点似乎是阶级过多。不将
A
扩展到AButMore
,而是从AButMore
构造A
并委派所有复制的方法。但是,委托代码对我而言似乎总是很愚蠢,尤其是当所有可以继承的方法都将被委托而没有任何修改时。让
Prototypeable
指定Object
作为返回类型,并让工厂采用Class
参数进行转换。不利之处在于,如果使用不当,可能会导致不安全的转换。编辑:澄清:目的是制造具有某种顺序依赖关系的实例,而没有类变量。最简单的示例是,如果它们每个都有一个索引变量-basePrototype将提供一个0索引的实例,而nextPrototype()将提供一个index + 1实例(基于调用该方法的实例的索引)。该特定情况有点简单(可能可以以更简单的方式实现),但涵盖了这个想法。
编辑:为了进一步澄清,这是确切的当前实现(我正在使用上面的第三个替代方法):
public class BuildFromPrototype {
public static <T extends Prototypeable> List<T> build(int buildCount, Class<T> protoClass, T prototype) {
if (protoClass==null || prototype==null || buildCount<=0) return null;
if( protoClass.isInstance(prototype.basePrototype()) && protoClass.isInstance(prototype.nextPrototype()) ) {
List<T> result = new ArrayList<T>(buildCount);
T pHolder = protoClass.cast(prototype.basePrototype());
result.add(pHolder);
for (int i=1;i<buildCount;i++)
result.add(pHolder = protoClass.cast(pHolder.nextPrototype()));
return result;
} else return null;
}
public interface Prototypeable {
public Object nextPrototype();
public Object basePrototype();
}
}
我认为这可以解决滥用问题(返回
null
是一种选择,Exception
也很合理),但是测试有效的强制转换可能会很昂贵。这种类型的转换可能也很昂贵-我对Class
类了解不多。 最佳答案
我不确定要定义“下一个”版本要做什么,似乎要进行元类编程,这在Java中是无法做到的,即我看不到如何拥有泛型类型系统管理在运行时确定的一系列类型,因为它们已被类型擦除并且在运行时不存在。定义从一种类型到另一种类型的映射的接口怎么样?就像是
public interface PrototypeMapping<U extends Prototypeable<Type>,V extends U>{
public V mapTo(U u);
}