接口如何包含在其签名或返回类型中引用接口的具体实现类型的方法?

Mic*_*wan 14 java generics interface return-type method-signature

假设我正在设计类似以下界面:

public interface MyInterface{
  public MyInterface method1();
  public void method2(MyInterface mi);
}
Run Code Online (Sandbox Code Playgroud)

但是,有一点需要注意,返回类型for method1和参数method2匹配具体实现而不仅仅是MyInterface.也就是说,如果我有MyInterfaceImpl这个实现MyInterface,它需要具有以下内容:

public class MyInterfaceImpl implements MyInterface{
  @Override
  public MyInterfaceImpl method1(){...}

  @Override
  public void method2(MyInterfaceImpl mi){...}
}
Run Code Online (Sandbox Code Playgroud)

如上所述,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);
}
Run Code Online (Sandbox Code Playgroud)

这将得到我想要的一个例外:其他实现可能会传递错误的泛型类型(没有任何力量T来匹配具体类型).所以其他人可能会实现以下内容:

public class NotMyInterfaceImpl implements MyInterface<MyInterfaceImpl>{
  @Override
  public MyInterfaceImpl method1();

  @Override
  public void method2(MyInterfaceImpl mi);
} 
Run Code Online (Sandbox Code Playgroud)

即使NotMyInterfaceImpl 应该实现,也会很好地编译MyInterface<NotMyInterfaceImpl>.*这让我觉得我需要别的东西.

*请注意,我不认为我试图违反LSP; 我很好,返回类型/参数是子类NotMyInterfaceImpl.

所以我不知道干净的方法.这让我相信我可能过于关注界面中的实现细节,但对我来说似乎并不是这样.有没有办法做我描述的那种东西,或者这是某种气味,我把东西放在一个不属于那里的界面?

new*_*cct 13

这是Comparable接口所面临的确切情况(其compareTo方法希望采用与调用它的对象相同的类型).那它是做什么的?它被简单地定义为Comparable<T>.这个想法是一个实现类"应该" Comparable自己实现作为参数(允许它"自我比较"); 但这没有强制执行(因为没有办法实现).

是的,正如您所指出的,这将允许任何类Comparable使用任何其他类的参数来实现:class Foo implements Comparable<Bar>where FooBar彼此没有关系.但是,这不是一个真正的问题.

需要Comparable对象的所有方法和类(排序,最大值等)都具有以下泛型类型约束<T extends Comparable<? super T>>.这确保了类型T的对象与它们自身相当.这样,它完全是类型安全的.因此,强制执行不是在Comparable接口的声明中,而是在使用它的地方.

(我注意到你<T extends MyInterface<T>>Comparable使用时只是简单使用<T>.虽然<T extends MyInterface<T>>会排除类型参数没有实现的情况MyInterface,但它不会排除类型参数实现的情况MyInterface,但是不同于类.所以有什么意思是半排除一些如果您采用Comparable限制使用它的方式,无论如何它都是类型安全的,所以添加更多限制没有意义.)