【问题标题】:Java interface function returning class that implements itJava接口函数返回实现它的类
【发布时间】:2019-12-19 12:15:15
【问题描述】:

我有一个带有当前返回自身的函数的接口。但是,我希望任何实现类都返回该类而不是基接口。 例如,在这个简化的例子中,这很好用:

public interface MyInterface<T, U> {
    public void foo(T t, U u);

    public MyInterface baz();
}

public class MyClass<T, U> implements MyInterface<T, U> {
    @Override
    public void foo(T t, U u) {}

    public MyClass bar() {
        return this;
    }

    @Override
    public MyInterface baz() {
        return this;
    }
}

但是如果我把最后一个函数改成这样:

@Override
public MyClass baz() {
    return this;
}

这显然失败了,因为覆盖函数不再匹配接口中的声明。

我需要 baz() 返回 Class 而不是 Interface 的原因是因为调用者可以按任意顺序调用 bar 和 baz 任意次数,但目前所有 bar() 调用必须在所有 baz() 调用之前, 除非我们一再地低调它。

更复杂的是使用两种泛型类型的 foo() 函数。我研究了使用奇怪的重复泛型模式,但无法找到合理的解决方案,因为 Interface 已经处理泛型,即使没有它。

有没有办法解决这个问题?谢谢!

【问题讨论】:

  • 为什么你认为被覆盖的baz() 不能返回Class?你试过了吗?
  • 为什么要返回接口和类的原始形式?此外,Java 具有返回类型协变;您可以覆盖 baz 以返回 ClassClass&lt;T, U&gt; 一旦消除原始。 (我知道这只是一个例子,但由于现有的java.lang.Class 类,这是一个糟糕的类名选择。)
  • 我很抱歉@shmosel。我认为我的代码因返回类型Class 而失败的原因是由于重载问题。真正的原因是因为在我的实际实现中,baz()函数是在InterfaceClass之间的一个抽象类中实现的,所以即使返回AbstractClass,这也不足以令人沮丧Class 使用。感谢@rgettman 的建议,我没有使用返回类型协方差的原因是因为它不是具体类的多个继承层的易于扩展的解决方案

标签: java generics inheritance


【解决方案1】:

如果你希望接口返回一个定义的类型,那么你需要另一个类型参数(例如命名为W),并且你要确保该类型是Interface,所以:

public interface MyInterface<T, U, W extends MyInterface<T, U, W>> {
    public void foo(T t, U u);

    public W baz();
}

public class MyClass<T, U> implements MyInterface<T, U, MyClass<T, U>> {
    @Override
    public void foo(T t, U u) {}

    public MyClass<T, U> bar() {
        return this;
    }

    @Override
    public MyClass<T, U> baz() {
        return this;
    }
}

注意:添加前缀 My 以避免与名为 Class 的内置类混淆。

【讨论】:

    猜你喜欢
    • 2019-12-17
    • 2012-10-06
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    相关资源
    最近更新 更多