如何将非泛型接口扩展为通用接口?

问题描述 投票:4回答:1

我正在尝试扩展TemporalAdjuster以便看起来像,

public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> {

    T adjustInto(T temporal);
}

当我试图直接扩展基接口时,

public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
        extends TemporalAdjuster {

    T adjustInto(T temporal);
}

我收到了一个错误。

... java:name clash:...有相同的擦除,但都没有覆盖另一个

有没有办法做到这一点?

到目前为止,我做到了。

public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> { //extends TemporalAdjuster {

    static <T extends Temporal & Comparable<? super T>> TypedTemporalAdjuster<T> of(
            final Class<T> temporalClass, final TemporalAdjuster temporalAdjuster) {
        return temporal -> temporalClass.cast(temporalAdjuster.adjustInto(temporalClass.cast(temporal)));
    }

    T adjustInto(T temporal);
}
java generics java-8 functional-interface
1个回答
7
投票

您不能覆盖具有更多限制性参数的方法,即T adjustInto(T temporal);不会覆盖Temporal adjustInto(Temporal temporal);,因为参数类型TTemporal更具限制性。所以你现在有两个名为adjustInto的方法,但是由于类型擦除,参数类型在字节码级别上是相同的,因为T extends Temporal & Comparable<? super T>被删除到Temporal

您可以通过将声明更改为来解决此问题

public interface TypedTemporalAdjuster<T extends Comparable<? super T> & Temporal>
extends TemporalAdjuster {
    T adjustInto(T temporal);
}

然后,语义上相同的T extends Comparable<? super T> & Temporal被删除到Comparable而不是Temporal。您也可以使用被删除到T extends Object & Comparable<? super T> & TemporalObject(通常,这种知识仅在您需要与前Generics代码兼容时才相关)。

然而,基本问题仍然存在,adjustInto(T temporal);不会覆盖adjustInto(Temporal temporal);,因为T是一个更严格的参数,所以现在,接口不再是一个功能接口,因为它有两个抽象方法。

qazxsw poi的子界面必须提供其所有操作,包括接受任何TemporalAdjuster的qazxsw poi。所以你只能这样做

adjustInto

但是,这样的包装调整器无法确保正确的参数,只能隐藏仍然可能在运行时失败的类型转换。但是看起来你试图在这里解决一个不存在的问题,因为你可以简单地在时间上使用Temporal方法来获得一个类型安全的操作,例如

public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
extends TemporalAdjuster {

    static <T extends Temporal & Comparable<? super T>> TypedTemporalAdjuster<T> of(
            final Class<T> temporalClass, final TemporalAdjuster temporalAdjuster) {
        return temporal -> temporalClass.cast(temporalAdjuster.adjustInto(temporal));
    }

    @Override T adjustInto(Temporal temporal);
}

这比你的包装更强大,就像你做的那样,例如

with

根据TemporalAdjuster a = TemporalAdjusters.lastDayOfMonth(); LocalDate date1 = LocalDate.now(), date2 = date1.with(a); LocalDateTime dateTime1 = LocalDateTime.now(), dateTime2 = dateTime1.with(a); ZonedDateTime zoned1 = ZonedDateTime.now(), zoned2 = zoned1.with(a); 操作,您只定义一次操作,而通过动态转换它们而不是转换,它可以用于其他时间。

© www.soinside.com 2019 - 2024. All rights reserved.