扩展“最终”接口/封闭的代码库接口

时间:2014-08-28 12:16:58

标签: java generics java-8

让我们说我希望扩展类似 Stream Java 8接口(我只使用此接口作为示例来说明一点)。为简化我的示例,我们假设界面只有两种方法,并且是最终的:

public final interface Stream<T> {

    Stream<T> limit(long maxSize);
    <R> Stream<R> map(Function<? super T,? extends R> mapper);
}

现在,对于我所有不同的项目,我可能想要编写特定于项目的不同扩展方法,但我不想要做的是在我的扩展类中实现整个Stream接口。

所以我在想,编写一个抽象扩展类,当我想编写一组新的扩展时,我可以扩展它。所以我在实施方面做得很远:

public abstract class AbstractStreamExtensions<A extends Stream<T>, T> implements Stream<T> {

    private final Stream<T> stream;
    private final Constructor<?> constructor;

    public AbstractStreamExtensions(Stream<T> stream) {
        this.stream = stream;

        try {
            constructor = this.getClass().getDeclaredConstructor(Stream.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public A limit(long maxSize) {
        try {
            return (A) constructor.newInstance(stream.limit(maxSize));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

具体课程看起来像这样:

public class StreamExtensions<T> extends AbstractStreamExtensions<StreamExtensions<T>, T> {

    private final Stream<T> stream;

    public StreamExtensions(Stream<T> stream) {
        super(stream);
        this.stream = stream;
    }

    public StreamExtensions<T> limit5() {
        return new StreamExtensions<>(stream.limit(5));
    }
}

将使用这样的:

Stream<String> stream = // ...
StreamExtensions<String> = new StreamExtensions(stream).map(...).limit5()

我希望你能看到我在这里想要实现的目标。在我的想法中,我仍然可以获得相同的Stream自动完成API,而无需再次实现现有的界面。

上面的代码不会编译,这是因为接口上没有map()函数的实现。现在我可以在具体的StreamExtensions课程中轻松实现这个,如果我愿意,但我更喜欢在AbstractStreamExtensions中使用它,因为它只是调用Stream方法像limit()那样。

有没有一种方法可以在map()基类中实现AbstractStreamExtensions的实现,它将在使用eclipse和intellij的自动完成和文档功能时编译并提供类型?

0 个答案:

没有答案