因此遵循 Java - Inherited Fluent method return type to return incident class' type, not parent's 中描述的解决方案。我想将其扩展到多个级别。
该解决方案显然在一个级别上有效。这是已编译且可运行的代码(无依赖项):
public enum X {
;
static interface BaseFoo<T, S extends BaseFoo<T, S>> {
S foo();
}
static interface Foo<T> extends BaseFoo<T, Foo<T>> {
void foo1();
}
static abstract class AbstractFooBase<T, S extends BaseFoo<T, S>> implements BaseFoo<T, S> {
abstract void internalFoo();
@Override
public S foo() {
internalFoo();
return (S)this;
}
}
static class FooImpl<T> extends AbstractFooBase<T, Foo<T>> implements Foo<T> {
@Override
void internalFoo() {
System.out.println("inside FooImpl::internalFoo()");
}
@Override
public void foo1() {
System.out.println("inside FooImpl::foo1()");
}
}
public static void main(String[] args) {
Foo<String> foo = new FooImpl<String>();
foo.foo().foo1();
}
}
但是,当我在对象继承层次结构中添加新级别时,事情变得困难。下面的代码无法编译:
public enum X {
;
static interface BaseFoo<T, S extends BaseFoo<T, S>> {
S foo();
}
static interface Foo<T> extends BaseFoo<T, Foo<T>> {
void foo1();
}
static interface BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S> {
S bar();
}
static interface Bar<T> extends BaseBar<T, Bar<T>> {
void bar1();
}
static abstract class AbstractFooBase<T, S extends BaseFoo<T, S>> implements BaseFoo<T, S> {
abstract void internalFoo();
@Override
public S foo() {
internalFoo();
return (S)this;
}
}
static class FooImpl<T> extends AbstractFooBase<T, Foo<T>> implements Foo<T> {
@Override
void internalFoo() {
System.out.println("inside FooImpl::internalFoo()");
}
@Override
public void foo1() {
System.out.println("inside FooImpl::foo1()");
}
}
static abstract class AbstractBarBase<T, S extends BaseBar<T, S>> extends FooImpl<T> implements BaseBar<T, S> {
abstract void internalBar();
@Override
public S bar() {
internalBar();
return (S)this;
}
}
static class BarImpl<T> extends AbstractBarBase<T, Bar<T>> implements Bar<T> {
@Override
void internalBar() {
System.out.println("inside BarImpl::internalBar()");
}
@Override
public void bar1() {
System.out.println("inside BarImpl::bar1()");
}
}
public static void main(String[] args) {
Foo<String> foo = new FooImpl<String>();
foo.foo().foo1();
Bar<Boolean> bar = new BarImpl<Boolean>();
bar.foo().bar1();
}
}
编译时错误消息是:
X.java:40: X.BaseFoo cannot be inherited with different arguments: <T,S> and <T,X.Foo<T>>
static abstract class AbstractBarBase<T, S extends BaseBar<T, S>> extends FooImpl<T> implements BaseBar<T, S> {
^
X.java:49: X.BaseFoo cannot be inherited with different arguments: <T,X.Bar<T>> and <T,X.Foo<T>>
static class BarImpl<T> extends AbstractBarBase<T, Bar<T>> implements Bar<T> {
^
Note: X.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors
知道如何解决这个问题吗?
最佳答案
这是您的继承层次结构:
正如您所看到的,其中一些类型多次继承相同的接口(interface)类型。事实上,BarImpl
实现BaseFoo
四次以上,并且某些继承链为其类型参数S
提供不同的参数。 。可以说BarImpl
实现以下内容:
-
BaseFoo<T, Foo<T>>
(来自Foo
) -
BaseFoo<T, Foo<T>>
(来自FooImpl
) -
BaseFoo<T, Bar<T>>
(来自Bar
) -
BaseFoo<T, Bar<T>>
(来自BarImpl
)
The same interface cannot be implemented with different type arguments ,因此您会收到编译器错误。
正如我在您的后续问题中指出的那样,我的回答 here讨论如何正确模拟“ self 类型”来实现分层流畅的构建器模式,就像您尝试做的那样。在其中,我指出需要在所有中间类型中维护一个变量“ self 类型”(代码中的 S
) - 仅使用被理解为 final
的“叶类”来解析它。 。您的代码违反了该规则,因为中间类型 Foo
, Bar
,和FooImpl
过早解决S
.
以下解决方案可以解决该问题:
static interface BaseFoo<T, S extends BaseFoo<T, S>> {
S foo();
}
static interface Foo<T, S extends Foo<T, S>> extends BaseFoo<T, S> {
void foo1();
}
static interface BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S> {
S bar();
}
static interface Bar<T, S extends Bar<T, S>> extends BaseBar<T, S> {
void bar1();
}
static abstract class AbstractFooBase<T, S extends BaseFoo<T, S>> implements BaseFoo<T, S> {
abstract void internalFoo();
@Override
public S foo() {
internalFoo();
return (S)this;
}
}
static abstract class AbstractIntermediateFoo<T, S extends AbstractIntermediateFoo<T, S>> extends AbstractFooBase<T, S> implements Foo<T, S> {
@Override
void internalFoo() {
System.out.println("inside FooImpl::internalFoo()");
}
@Override
public void foo1() {
System.out.println("inside FooImpl::foo1()");
}
}
static final class FooImpl<T> extends AbstractIntermediateFoo<T, FooImpl<T>> { }
static abstract class AbstractBarBase<T, S extends AbstractBarBase<T, S>> extends AbstractIntermediateFoo<T, S> implements BaseBar<T, S> {
abstract void internalBar();
@Override
public S bar() {
internalBar();
return (S)this;
}
}
static final class BarImpl<T> extends AbstractBarBase<T, BarImpl<T>> implements Bar<T, BarImpl<T>> {
@Override
void internalBar() {
System.out.println("inside BarImpl::internalBar()");
}
@Override
public void bar1() {
System.out.println("inside BarImpl::bar1()");
}
}
public static void main(String[] args) {
FooImpl<String> foo = new FooImpl<String>();
foo.foo().foo1();
BarImpl<Boolean> bar = new BarImpl<Boolean>();
bar.foo().bar1();
}
我的更改如下:
- 维护
S
在Foo
- 维护
S
在Bar
- 拆分
FooImpl
分为以下内容:-
AbstractIntermediateFoo
,即abstract
,维持S
,并实现internalFoo
和foo1
. -
FooImpl
,具体而言,final
,并解决S
.
-
- 制造
BarImpl
final
. - 在
main
,声明foo
和bar
如FooImpl
和BarImpl
- 接口(interface)编码在这里不可行。
关于Java继承多级层次结构中的Fluent方法返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19417082/