【发布时间】:2011-09-29 22:21:10
【问题描述】:
假设我正在设计类似下面的界面:
public interface MyInterface{
public MyInterface method1();
public void method2(MyInterface mi);
}
但是,需要注意的是method1 的返回类型和method2 的参数与具体实现匹配,而不仅仅是MyInterface。也就是说,如果我有实现MyInterface 的MyInterfaceImpl,它需要具有以下内容:
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 的子类。
所以我不知道有一种干净的方法可以做到这一点。这让我相信我可能过于关注接口中的实现细节,但对我来说似乎不是这样。有什么方法可以做我描述的那种事情,或者这是我在不属于那里的界面中放入了某种气味?
【问题讨论】:
-
我不想这样说无礼,但通常试图制作一个需要知道其底层实现的接口,这表明根本缺乏对接口的目的。您可能需要从设计中退后一步。
-
好吧,如果您阅读了我的最后一段,我有点担心我可能违反了我应该对界面执行的操作。
标签: java generics interface return-type method-signature