返回实现它的类的Java接口函数

返回实现它的类的Java接口函数,java,generics,inheritance,Java,Generics,Inheritance,我有一个接口,该接口具有一个当前返回自身的函数。但是,我希望任何实现类都返回该类而不是基接口。 例如,在这个简化的示例中,这很好: public interface MyInterface<T, U> { public void foo(T t, U u); public MyInterface baz(); } public class MyClass<T, U> implements MyInterface<T, U> { @O

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

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;
    }
}
这显然是失败的,因为重写函数不再匹配接口中的声明

我之所以需要baz()来返回类而不是接口,是因为调用方可以按任意顺序调用bar和baz任意次数,但当前所有的bar()调用必须在所有baz()调用之前,除非我们反复向下转换它

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


有办法解决这个问题吗?谢谢

如果希望接口返回已定义的类型,则需要另一个类型参数(例如名为
W
),并确保该类型是
接口,因此:

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;
    }
}
公共接口MyInterface{
公开无效foo(T,U);
公共W baz();
}
公共类MyClass实现MyInterface{
@凌驾
公共无效foo(T,U){
公共MyClass bar(){
归还这个;
}
@凌驾
公共MyClass baz(){
归还这个;
}
}

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

为什么您认为被重写的
baz()
不能返回
class
?您试过了吗?为什么返回接口和类的原始形式?而且,Java具有返回类型协方差;您可以覆盖
baz
以返回
Class
,或者在原始度消除后返回
Class
。(我知道这只是一个例子,但由于现有的
java.lang.class
class),这是一个糟糕的类名选择。)可能重复的可能重复:以及。我的道歉@shmosel。我认为我的代码在返回类型
Class
时失败的原因是重载问题。实际原因是,在我的实际实现中,
baz()
函数是在
接口
之间的抽象类中实现的,因此即使它返回
抽象类
,这也不足以让
使用。感谢@rgetman的建议,我没有使用返回类型协方差的原因是,对于具体类的多个继承层来说,它不是一个易于扩展的解决方案
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;
    }
}