我有一个接口(interface)来描述类何时可以创建自身的“下一个”版本:
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>
,但这是不允许的(不能使用不同的类多次实现通用接口(interface))。另请注意 A
和AButMore
两者都实现了一些其他接口(interface),并且该实现与A
相同。至AButMore
.
关于解决这个问题的建议?我似乎无法解决一般问题,所以我考虑了一些替代设计:
伪装饰这两个类 - 即具有不实现
Prototypeable
的基类接口(interface),从该接口(interface)继承到适当的子类,然后将两个类扩展为它们自己的原型(prototype)版本。缺点似乎是类太多。不延长
A
至AButMore
而是构建AButMore
来自A
并委托(delegate)所有复制的方法。然而,委托(delegate)代码对我来说总是显得很愚蠢,尤其是当每个可以继承的方法都将在不进行任何修改的情况下进行委托(delegate)时。有
Prototypeable
指定Object
作为返回类型,并让工厂采用Class
类型转换参数。这里的缺点是,如果使用不当,可能会导致不安全的强制转换。
编辑:澄清一下:目的是制造具有某种顺序依赖性的实例,而不具有类变量。最简单的例子是,如果它们每个都有一个索引变量 - basePrototype 将提供一个 0 索引实例,而 nextPrototype() 将提供一个索引+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中是做不到的,即我看不到如何让通用类型系统管理运行时确定的一系列类型,因为它们被类型删除并且在运行时不存在。定义从一种类型到下一种类型的映射的接口(interface)怎么样?类似的东西
public interface PrototypeMapping<U extends Prototypeable<Type>,V extends U>{
public V mapTo(U u);
}
关于java - 继承+接口(interface)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1631912/