假设我正在设计类似以下界面的东西:
public interface MyInterface{
public MyInterface method1();
public void method2(MyInterface mi);
}
但是,需要注意的是,for 的返回类型method1
和参数method2
与具体实现相匹配,而不仅仅是MyInterface
. 也就是说,如果我有MyInterfaceImpl
该 implements MyInterface
,它需要具有以下内容:
public class MyInterfaceImpl implements MyInterface{
@Override
public MyInterfaceImpl method1(){...}
@Override
public void method2(MyInterfaceImpl mi){...}
}
如上所述,method1
不会导致任何编译错误,但无法保证返回类型在所有实现中都匹配。当然method2
甚至不会编译,因为签名与接口不匹配。
一种候选解决方案是在泛型中使用自引用或递归边界:
public interface MyInterface<T extends MyInterface<T>>{
public T method1();
public void method2(T mi);
}
public class MyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
@Override
public MyInterfaceImpl method1();
@Override
public void method2(MyInterfaceImpl mi);
}
这会让我得到我想要的一个例外:其他实现可能会传递错误的泛型类型(没有任何力量T
与具体类型相匹配)。所以可能其他人可以实现以下内容:
public class NotMyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
@Override
public MyInterfaceImpl method1();
@Override
public void method2(MyInterfaceImpl mi);
}
即使NotMyInterfaceImpl
应该实现MyInterface<NotMyInterfaceImpl>
.* 这也可以编译得很好。这让我觉得我需要别的东西。
*请注意,我不认为我试图违反 LSP;我可以接受返回类型/参数是NotMyInterfaceImpl
.
所以我不知道有一种干净的方法来做到这一点。这让我相信我可能过于关注接口中的实现细节,但对我来说似乎不是这样。有什么办法可以做我描述的那种事情,或者这是我在一个不属于那里的界面中放入一些东西的某种气味?