我有一个接口来描述类何时可以创建其自身的“下一个”版本:

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>,但是这是不允许的(无法使用不同的类多次实现通用接口)。还要注意,AAButMore都实现了其他一些接口,并且从AAButMore的实现是相同的。

有关解决此问题的建议?我似乎无法解决通用问题,因此我考虑了一些替代设计:


伪装饰这两个类-即,具有不实现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);
}

08-04 19:00