2013-10-17 27 views
3

这是Java inherited Fluent method return type in multiple level hierarchies的简化版本。BaseFoo不能使用不同的参数继承:<T,X.Bar<T>>和<T,X.Foo<T>>

考虑下面的代码:

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> { 
     ^

任何人有任何解决方案?

Disclaim:我试图使用该模式跨容器类继承层次结构实现fluent interface

背景:让人们更容易理解为什么我需要这个,这里是故事。我想创建一个容器系列:Traversal < - Sequence < - List。所以Traversal有一个方法Traveral<T> accept(Visitor<T>)(简称no PECS),这个方法应该总是返回this迭代访问者通过元素。当我有一个List类型,我希望该方法返回List<T>,而不是Traversal<T>,因为我想让它可以调用类似myList.accept(v).head(15),其中head(int)List方法不Traversal

+0

我的答案[here](http://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current-type-with-a-type-variable/7355094 #7355094)似乎有关。 –

+0

@PaulBellora这真是一个全面的答案。尼斯。我想这是OP在这里需要的。 –

+0

是的@PaulBellora,我之前读过。但我的情况是关于一个容器继承系列,它引入了另一个''类型。你能想出一个基于我的代码的解决方案吗? –

回答

7

类或接口无法实现或扩展来自通用接口的不同实例化。你的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接口试图从2个不同的实例BaseFoo,这是非法的。让我们来了解使用一个简单的例子的原因:

// 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) { ... } 
} 

因此,这会导致在类中创建重复的桥接方法。这就是为什么它不被允许。

+0

我知道这是非法的,而我需要的是如何解决或解决它。 ''是'Foo '的一种,所以我假设根'BaseFoo >'可以被替换为'BaseFoo ',这与通过'BaseBar'的另一个继承路由相同,isn是吗? –

+0

@green不,不是那样的。 'List '不是'List '。使用泛型时不会遵循类型之间的固定关系。 –

+0

谢谢Rohit。无论如何努力实现我想要的,即。一个容器层次结构中流畅的API? –

相关问题