具有参数化方法类型的通用接口

generic interface with parameterized method types

我试图创建一个通用接口,因为这些方法几乎用在我拥有的所有服务中,但是当我试图实现这些方法时,我得到的只是一个“方法不覆盖其超类的方法”。

@Service
public interface CustomInterface {

    <T, R> List<T> get(final R req);

    <T> T getById(final String id);

    <T, R> T create(final R req);

    <T, R> T update(final String id, final R req);

    <T, R> T patch(final String id, final R req);

    <T> T delete(final String id);

}
///// This is the implementation of one of the methods!
@Override
public CustomerResponseObject create(final CustomObject req) {
    return null;
}

我做错了什么?我真的认为这会奏效!

你似乎误解了泛型。

至关重要的是,他们 link 事情。它们是编译器想象力的虚构(JVM 运行时不知道泛型是什么,不应用它们,不关心它们——而且大多数泛型实际上在编译期间被完全消除,它们不在 class 文件),因此它们的唯一目的是让编译器帮助您解决问题并通知您在哪里可能出现输入错误。

因此,他们 link - 他们让你对编译器说:“嘿,这个方法?它可以接受一些对象,该对象是 class 即 Number 或其子类型。然后,它 return 与给定的类型相同”。它可以让你 link return 类型到一个参数的类型,或者 link 两个参数类型在一起,或者它们可以 link 显示的列表的组件类型作为 class 中的字段到 class 中其他地方的方法的参数,等等

如果你的泛型类型只出现在一个地方,那是没用的

因此,您在示例中使用的每个类型参数都是完全无用的,因此我断定您不了解该机制。

<T, R> T create(final R req);表示如下:

对于调用此 create 方法的任何给定调用,有些类型我们将规定为 T,有些类型我们将称为 R,仅用于此方法调用(相对于泛型类型本身,每个实例都是有效的)。它们没有边界(<T extends Number> 被称为 'bound'。只是 <T> 意味着它是无限的;任何类型都可以。

return类型为T,参数为R。

鉴于没有边界,这只是一种奇怪的写法:

Object create(Object req);

你实现的不是那个。

<T, R> 在此构造中 声明 类型变量;它们的所有其他出现 使用 它们。鉴于您已在此处为每个方法声明了它们,因此它们都是完全不相关的类型变量。是这样的:

void foo() {
    int x = 5;
}

void bar() {
    int x = 10;
}

这两个局部变量之间存在 关系。它们都被命名为 x,这并没有使它们完全相关。这同样适用于您的代码:每个方法都有自己独特的类型 var;他们都被命名为 T 或 R 的事实并没有使他们彼此之间更加相关。

据推测,您打算为这个自定义接口做的,类型 相关的。

这意味着它需要是类型本身的 属性:

public interface CustomerInterface<T, R> {
    List<T> get(R req);
    T getById(String id);
    T create(R req);
    // etc
}

现在所有那些 Ts 和 Rs 实际上指的是同一件事,现在你正在 linking 东西。然后你可以编写一个编译良好的实现:

public class MyCustomImpl implements CustomerInterface<CustomObject, CustomerResponseObject> {
    public CustomerResponseObject create(final CustomObject req) {
      ..
    }
}

这将编译得很好。

注意:不要在接口方法中使用参数'final' - 这是毫无意义的代码混乱。

接口中使用的方法必须在实现原始接口代码的class中被“覆盖(每个接口方法签名的完整代码)”。 方法签名的接口定义充满了没有主体代码的抽象签名。 正确的 class 对象将具有完整的可用编码方法签名。 当编写 class 来实现接口时,类型化的多态因子允许 class 实例被引用为与接口类型相同而不是 class 的类型,但是 class 实例既是类型,也是从 class 的新实例变量实例化的接口类型变量的任何实例。