2013-02-01 34 views
3

这些接口是非常简单的:在从属接口上强制实施参数类型?

public interface Thawed<F> 
{ 
    F freeze(); 
} 

public interface Frozen<T> 
{ 
    T thaw(); 
} 

这工作,没有任何问题。

但现在,我怎么会需要ThawedF实施FrozenTFrozen实现Thawed

我能得到的最接近的是:

public interface Thawed<F extends Frozen<? extends Thawed<F>>> 

public interface Frozen<T extends Thawed<? extends Frozen<T>>> 

但是,这听起来很递归......(还与Thawed<?>Frozen<?>

回答

1

我能得到的最接近的是

这是正确的答案;你不能比Java类型系统中的更好。


注意,这确实允许

class Cat implements Thawed<Dog> { } 
class HouseCat extends Cat { } 
class Dog implements Frozen<HouseCat> { } 

您可以防止通过使用两个通用参数:

public interface Thawed<F extends Frozen<T, F>, T extends Thawed<F, T>> { } 

public interface Frozen<T extends Thawed<F, T>, F extends Frozen<T, F>> { } 

不过,我认为这是太混乱是有益的。

这也将仍然允许

class Cat implements Thawed<Dog, HouseCat> { } 

class HouseCat extends Cat { } 

class Dog implements Frozen<HouseCat, Dog> { } 
+0

是的,使用它的类都是“最终”的 - 在我的代码,至少。当其他人使用它时,不能保证这一点;)谢谢你清除我的疑惑! – fge

+0

@fge:第二个想法,你可以比这更好。 – SLaks

3

我认为这应该工作:

public interface Thawed<F extends Frozen<?>> { ... } 

public interface Frozen<T extends Thawed<?>> { ... } 

我不认为你需要更深入的东西,因为你需要做的只是指定F是某种Frozen (并且类似地对于T)。

+1

'类Cat实现解冻''Dog类实现冷冻' – SLaks

+1

@SLaks - 但Thawed'的'定义要求'Dog'延长冻结'' (等)这是OP想要的。 OP没有说这两个类需要互相逆转(例如,当你冻结一个“猫”时你返回的'Frozen')会在解冻时再次产生一个'Cat',这可能会产生狗粮。 :) –

+0

我认为这是暗示。 – SLaks