这是Java inherited Fluent method return type in multiple level hierarchies的简化版本。
给出以下代码:
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>>, Foo<T> {
void bar1();
}
}
运行
javac X.java
我收到错误消息:X.java:15: error: BaseFoo cannot be inherited with different arguments: <T,X.Bar<T>> and <T,X.Foo<T>>
static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T> {
^
有人有什么解决办法吗?
免责声明:我正在尝试使用该模式在整个容器类继承层次结构中实现fluent interface。
背景:为了使人们更容易理解我为什么需要它,这里是故事。我想创建一个容器系列:
Traversal
Sequence List。因此Traversal
有一个Traveral<T> accept(Visitor<T>)
方法(简称为PECS),该方法应在对元素进行访问者迭代之后始终返回this
。当我有List
类型时,我希望该方法返回List<T>
而不是Traversal<T>
,因为我希望可以调用类似myList.accept(v).head(15)
的名称,其中head(int)
是List
的方法,而不是Traversal
最佳答案
类或接口不能实现或从通用接口的不同实例扩展。您的Bar
接口违反了此规则。让我们检查一下接口声明:
static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T>
因此,
Bar<T>
扩展了两个接口:BaseBar<T, Bar<T>>
Foo<T>
除此之外,这两个接口还来自同一接口
BaseFoo
的不同实例。BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S>
Foo<T> extends BaseFoo<T, Foo<T>>
这些继承的接口最终还是
Bar
接口的超级接口。因此,您的Bar
接口尝试从BaseFoo
的2个不同的实例扩展为非法。让我们用一个简单的例子了解原因:// Suppose this was allowed
class Demo implements Comparable<Demo> , Comparable<String> {
public int compareTo(Demo arg) { ... }
public int compareTo(String arg) { ... }
}
然后在类型擦除之后,编译器将为两种通用方法生成2个桥接方法。该类被翻译为:
class Demo implements Comparable<Demo> , Comparable<String> {
public int compareTo(Demo arg) { ... }
public int compareTo(String arg) { ... }
// Bridge method added by compiler
public int compareTo(Object arg) { ... }
public int compareTo(Object arg) { ... }
}
因此,这导致在类中创建重复的桥方法。这就是为什么它是不允许的。