【发布时间】:2009-10-27 16:09:41
【问题描述】:
我有一个接口来描述一个类何时可以创建自己的“下一个”版本:
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,而是从As 构造AButMore并委托所有复制的方法。然而,委托代码在我看来总是很愚蠢,尤其是当每个可以被继承的方法都将被委托而无需修改时。具有
Prototypeable指定Object作为返回类型,并让工厂采用Class参数进行转换。这里的缺点是,如果使用不当,这可能会导致不安全的强制转换。
编辑:澄清一下:目的是制造具有某种顺序依赖性的实例,而没有类变量。最简单的例子是,如果它们每个都有一个索引变量——basePrototype 将提供一个 0-index 实例,而 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 类了解不多。
【问题讨论】:
-
如果(编辑)是这种情况,为什么不只是有一个接口 'Sequenced { int getIndex(); }'?
-
这个想法是制造顺序实例,顺序依赖比索引更复杂——这只是可以完成的最简单的事情的一个例子。
标签: java generics inheritance interface