从接口定义引用实现类

时间:2021-03-30 19:27:45

标签: java kotlin inheritance

给定一个接口 I

interface I<T> {
    public abstract T doSomthing(T other);
}

其中实现接口 C 的任何类 I 将始终使用自身 (C) 作为类型参数:

class MyClass implements I<MyClass> {

    @Override
    public MyClass doSomthing(MyClass other) {
        return null;
    }
}

有没有办法在每次新类实现接口时不显式传递类 C 作为参数来完成此操作?

换句话说,在接口中是否可以引用实现该接口的类?

3 个答案:

答案 0 :(得分:2)

tl;博士

你问:

<块引用>

有没有一种方法可以在不显式传递类 C

的情况下完成此操作

不,不是在 Java 中。

示例

您似乎准确地描述了与 Java 捆绑在一起的 Comparable<T> 接口的场景。该接口有一个通用参数,用于比较两个对象的类型。该接口需要一个方法 compareTo​(T o) 接受相同泛型类型的单个参数。

让我们看一下 OpenJDK 源代码中的示例用法,the source code 用于类 Year

该类将自身显式声明为正在实现的 Comparable 接口上的比较类型。

public final class Year
        implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable {

compareTo 方法明确引用自己的类作为要比较的类型。

@Override
    public int compareTo(Year other) {
        return year - other.year;
    }

你问:

<块引用>

有没有办法在每次新类实现接口时不显式传递类 C 作为参数来实现这一点?

似乎答案是。实现类必须显式地引用自己作为正在实现的接口的泛型类型的实现。

警告:(a) 我不是此类语言问题的专家。 (b) 我可能误解了你的问题。

答案 1 :(得分:2)

补充另一个答案:您所描述的是自我类型

其他一些语言有它(例如 Scala)。

但恐怕 Kotlin 不会。 (Java doesn't,或者。)

long discussion 关于将其添加到 Kotlin 未来版本的可能性;似乎潜在的用途可能不够广泛,以至于不值得,尽管似乎还没有最终达成共识。

通常的解决方法是使用类型参数 — 类似于 C++ 调用的 the curiously-recurring template pattern。正如这个问题所示,它在 Java 或 Kotlin 中并不完全类型安全,而是 covers most of the same ground

答案 2 :(得分:0)

这就是所谓的self-bounded generics。它可以在 Java 和 Kotlin 中声明。

Java:

interface I<T extends I<T>> {
    public abstract T doSomething(T other);
}

科特林:

interface I<T : I<T>> {
    fun doSomething(other: T): T
}

但这并不意味着,可以省略泛型参数,然后声明类,实现此接口。它只是对类型施加了额外的限制,您将其作为泛型参数传递(将其缩小到只有一种类型)。 Kotlin 和 Java 都不支持类声明的类型推断。

另见:Can I resolve a generic type from another generic declaration in an interface?