【问题标题】:How to implement a generic interface that extends another generic interface in Java?如何在 Java 中实现一个扩展另一个泛型接口的泛型接口?
【发布时间】:2021-10-09 18:54:48
【问题描述】:

我是 Java 新手,正在致力于实现通用接口,这就是我需要帮助的地方。

我想用 Java 实现一个通用接口,它扩展了另一个接口。这就是当前界面结构的样子 -

interface ItemsProviderInterface<ExtReq, ExtRes> 
extends GenericItemProviderInterface<ItemRequest, ExtReq, ExtRes, ItemResponse> {}


interface GenericItemProviderInterface<Req, ExtReq, ExtRes, Res>{
    ExtReq convertInput(Req req)
    Res convertResponse(ExtRes res)
    ExtRes request(ExtReq req)
}

我想实现ItemsProviderInterface 接口并为convertInput(), convertResponse(), request() 方法提供定义。

也许像 -

class itemsProvider<> implements ItemsProviderInterface<>

我不确定使用哪个泛型类型来定义类。对应于 ItemsProviderInterface 或 GenericItemProviderInterface 的泛型类型。我阅读了很多博客文章并在 StackOverflow 上搜索了一个类似的问题,但找不到。非常感谢任何帮助。

【问题讨论】:

  • 您正在实现ItemsProviderInterface,因此该接口是您关心的通用类型。现在,ExtReqExtRes 应该是什么类型,我们无法告诉您,因为这完全取决于您希望代码做什么。将您的 itemsProvider 声明为通用以及 class itemsProvider&lt;ExtReq, ExtRes&gt; implements ItemsProviderInterface&lt;ExtReq, ExtRes&gt; 或非通用并固定为特定类型可能是有意义的。class itemsProvider implements ItemsProviderInterface&lt;SomeType, AnotherType&gt; 其中SomeType 是一个实际类型,例如 String

标签: java class generics design-patterns interface


【解决方案1】:

我认为值得检查在这种情况下哪个标识符意味着什么。我们先看基础接口GenericItemProviderInterface&lt;Req, ExtReq, ExtRes, Res&gt;

这里所有4个类型参数ReqExtReqExtResRes都是类型参数。记住这一点很重要,因为它们本身不是类型!

那我们看下派生接口的定义:ItemsProviderInterface&lt;ExtReq, ExtRes&gt;只有2个类型参数:ExtReqExtRes。请注意,尽管名称相同,但它们本质上与基本接口上的名称没有任何关系。这种联系现在来了:

interface ItemsProviderInterface<ExtReq, ExtRes> 
extends GenericItemProviderInterface<ItemRequest, ExtReq, ExtRes, ItemResponse> 

这意味着ItemsProviderInterface is-a GenericProviderInterface 具有这样设置的 4 个类型参数:

  • GenericItemProviderInterfaceReq 设置为实际类型(类或接口)ItemRequest
  • GenericItemProviderInterfaceExtReq 设置为ItemsProviderItnerface 的类型参数ExtReq
  • GenericItemProviderInterfaceExtRes 设置为 ItemsProviderInterface 的类型参数 ExtRes
  • GenericItemProviderInterfaceRes 设置为实际类型ItemResponse

因此,基类的 4 个类型参数中的 2 个“固定”为特定类型,其余两个为左变量。

如果你现在实现ItemProviderInterface,你可以或者也有2个类型参数并将它们路由到ExtReq/ExtRes或者将它们固定到特定的类(或者做 1 和 1,但这对于这个特定的例子可能没有用。

所以要么

class MyItemProvider<ExtReq, ExtRes>
    implements ItemProviderInterface<ExtReq, ExtRes> {...}

class MySpecificItemProvider
    implements ItemProviderInterface<MySpecificExtReq, MySpecificExtRes> {...}

【讨论】:

    【解决方案2】:

    在您的用例中,类 itemsProvider 正在实现 ItemsProviderInterface,因此该类应该只处理实现接口所持有的泛型类型。

    你想在这个类中实现方法,你可以通过两种方式进行。既然你说你想提供方法的实现,我认为你需要方法的特定返回类型。在这种情况下,您可以继续这样做

    public class itemsProvider<String, Integer> implements ItemsProviderInterface<String, Integer> {
    

    这里我以调用时ExtReq和ExtRes分别为String和Integer类型为例

    【讨论】:

      【解决方案3】:

      我不确定使用哪种泛型类型来定义类。对应于 ItemsProviderInterface 或 GenericItemProviderInterface 的泛型类型。

      ItemsProvider 类直接实现ItemsProviderInterface,因此它必须为该接口定义的参数指定值。定义适用于GenericItemProviderInterface 扩展的参数是该接口(它忠实地执行)的责任。

      这在语义上可能有点晦涩难懂,但在语法上却是明确无误的,尤其是在子接口和超级接口具有不同数量参数的情况下。您在此 implements 子句中放在尖括号之间的参数值...

      implements ItemsProviderInterface<>
      

      ... 是子句中命名的接口的参数。如果您尝试提供错误的数量,那么编译器将拒绝您的代码。

      【讨论】:

        猜你喜欢
        • 2019-04-06
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        • 2021-05-05
        • 1970-01-01
        • 2012-10-17
        • 2020-11-28
        • 1970-01-01
        相关资源
        最近更新 更多