正如在評論中討論,你的設計的必要條件是getCopy
方法返回「自我型」 - 也就是說,一個BlueStack<T>
實施將有望從getCopy
返回BlueStack<T>
和RedStack<T>
應該返回一個RedStack<T>
等
不幸的是,在Java中沒有辦法表達「自我類型」。作爲zhong.j.yu points out,遞歸類型參數接近,例如:
//not recommended!
public interface Stack<S extends Stack<S, T>, T extends Item> {
S getCopy();
}
但作爲zhong.j.yu提到這是直觀和仍然無法阻止BlueStack<T>
從「說謊」和返回來自getCopy
的RedStack<T>
。
相反,我建議重新設計。嘗試解除從Stack
類型本身複製堆棧的責任。例如:
public interface StackCopier<S extends Stack<T>, T extends Item> {
S copy(S original);
}
如果StackCopier
實現需要訪問他們各自的Stack
S的私有成員,可以考慮讓他們嵌套類,例如:
class BlueStack<T extends Item> implements Stack<T> {
...
static class Copier<T extends Item> implements StackCopier<BlueStack<T>, T> {
@Override
public BlueStack<T> copy(BlueStack<T> original) {
...
}
}
當然SimpleFinder
會需要改變,以要麼有StackCopier<S, T>
字段,要麼將其作爲find
的新參數:
private final StackCopier<S, T> copier = ...;
public S find(S stack, int a) {
S stackCopy = copier.copy(stack);
...
return stackCopy;
}
最佳行動方案實現什麼?爲什麼你無法更改接口定義? – Bobulous
嘗試蠻力施放。有辦法解決它(遞歸類型參數),但它不值得。 – ZhongYu
@Arkanon,因爲它不是我的改變...:|而蠻力施展是相當醜陋的不是嗎? – SadStudent