返回实现它的类的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;
}
}