3

这是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();
    }

}

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

任何人有任何解决方案?

免责声明:我正在尝试使用该模式在容器类继承层次结构中实现流畅的接口。

背景:为了让人们更容易理解我为什么需要这个,这里是故事。我想创建一个容器系列:Traversal<- Sequence<- List。所以Traversal有一个方法Traveral<T> accept(Visitor<T>)(简称没有PECS),这个方法应该总是this在遍历元素之后返回。当我有一个List类型时,我希望方法返回List<T>而不是Traversal<T>因为我想让调用类似的东西成为可能myList.accept(v).head(15),其中head(int)的方法是ListnotTraversal

4

1 回答 1

11

类或接口不能实现或扩展通用接口的不同实例。您的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) { ... } 
}

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

于 2013-10-17T20:24:53.727 回答