Gel*_*Luo 3 java generics inheritance fluent-interface fluent
这是Java在多级层次结构中继承Fluent方法返回类型的简化版本.
给出以下代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
运行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> {
^
Run Code Online (Sandbox Code Playgroud)
有人有任何解决方案?
免责声明:我正在尝试使用该模式在容器类继承层次结构中实现流畅的接口.
背景:为了让人们更容易理解我为什么需要这个,这就是故事.我想创建一个容器系列:Traversal< - Sequence< - List.所以Traversal有一个方法Traveral<T> accept(Visitor<T>)(简称PECS),这个方法应该总是this在通过元素迭代访问者后返回.当我有一个List类型时,我希望方法返回List<T>而不是Traversal<T>因为我想让它可以调用类似的东西myList.accept(v).head(15),其中head(int)一个方法是ListnotTraversal
Roh*_*ain 10
类或接口不能从通用接口的不同实例化实现或扩展.您的Bar界面违反了此规则.我们来看看接口声明:
static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T>
Run Code Online (Sandbox Code Playgroud)
所以,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界面尝试从2个不同的实例化扩展BaseFoo,这是非法的.让我们用一个简单的例子来理解原因:
// Suppose this was allowed
class Demo implements Comparable<Demo> , Comparable<String> {
public int compareTo(Demo arg) { ... }
public int compareTo(String arg) { ... }
}
Run Code Online (Sandbox Code Playgroud)
然后在类型擦除之后,编译器将为通用方法生成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) { ... }
}
Run Code Online (Sandbox Code Playgroud)
因此,这导致在类中创建重复桥接方法.这就是为什么不允许这样做的原因.