当前位置: 首页 > 面试题库 >

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

公良奇
2023-03-14
问题内容

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

public interface MyInterface{
  public MyInterface method1();
  public void method2(MyInterface mi);
}

但是,需要注意的是,for的返回类型method1和参数method2匹配具体的实现,而不仅仅是MyInterface。也就是说,如果我具有MyInterfaceImpl该实现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

所以我不知道这样做的干净方法。这使我相信我可能会过多地关注界面中的实现细节,但对我而言似乎并非如此。有什么方法可以做我描述的事情,还是我在某种不属于该接口的接口中闻到这种气味?


问题答案:

这是Comparable接口所面临的确切情况(其compareTo方法希望采用与调用它的对象相同类型的参数)。那怎么办呢?简称为Comparable<T>。这个想法是,一个实现类“应该”
Comparable以自身作为参数来实现(允许它与自身“比较”)。但这不是强制性的(因为没有办法这样做)。

是的,正如你指出,这将允许任何类来实现Comparable与任何其他类的参数:class Foo implements Comparable<Bar>其中,FooBar没有关系对方。但是,这并不是真正的问题。

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

(I notice that you use <T extends MyInterface<T>> while Comparable uses
simply <T>. Although <T extends MyInterface<T>> will exclude cases where
the type parameter does not implement MyInterface, it will not exclude cases
where the type parameter does implement MyInterface, but is different than
the class. So what’s the point of half-excluding some cases? If you adopt
Comparable‘s way of restricting it where they are used, it’s type-safe
anyway, so there is no point in adding more restrictions.)



 类似资料:
  • 问题内容: 我在编写的程序中遇到接口问题。我想创建一个接口,该接口的方法之一可以接收/返回对自己对象类型的引用。就像这样: 我不能在“?”处使用“ I”,因为我不想返回对接口的引用,而是要返回对类的引用。我搜索后发现在Java中没有“自我引用”的方法,因此我不能仅用“?”代替。在示例中,“ self”关键字或类似的内容。实际上,我想出了一个解决方案 但这似乎确实是一种解决方法或类似方法。还有另一种

  • 问题内容: 我正在玩Go,发现一个我无法解决的问题。假设我有如下代码: 我导入了软件包并开始使用它: 我真的很喜欢我的助手“运行”,但是我想使其更加慷慨:我不希望人们总是向我传递MySQL客户端。可以是具有“ RunQuery”和“ Result”方法的任何东西。所以我尝试使用接口: 可悲的是,这不再编译了。我收到此错误: Go不支持此功能吗,或者我做错了什么? 问题答案: 应该返回接口,否则你总

  • 问题内容: 如何在实现类中强制执行方法getFoo(),返回相同实现类类型的列表。 现在,实现Bar的类将返回实现Bar的任何类的对象。我想使其更加严格,以便实现Bar的类在getFoo()中仅返回其类型的对象列表。 问题答案: 不幸的是,这不能由Java的类型系统强制执行。 但是,您可以通过使用以下方法来达到非常接近的效果: 然后您的实现类可以像这样实现它: 但是没有什么可以阻止另一个类这样做:

  • 问题内容: 我在接口上苦苦挣扎。考虑一下: 我希望函数返回a 或an ,具体取决于是否从或调用 当我尝试对此进行编译时,出现以下错误: 不能将s( StringGenerator类型)用作数组或切片文字中的Generator类型: StringGenerator不实现Generatorer(getValue方法的类型错误) 有getValue()字符串 要getValue() 我该如何实现? 问题

  • 好吧,乖点。 这里有一个枚举,它实现了一个接口,该接口返回一个“原始类型”,它给我一个关于接口中的方法的警告。 如果我将接口的方法更改为: 它会在的方法签名上变为未经检查的警告。如果我改变的签名: 然后返回有一个不兼容的类型错误,因为

  • 有一个界面WebElement。 我想做一个包装器UIElement,它实现了WebElement。 我已经重写了所有方法。 但是返回List的findElementS方法面临一个问题 这是我的方法,IDE没有给出上面的错误: 这是UIElement类和构造函数: