BaseFoo不能用不同的参数继承:< T,X.Bar< T>>和< T,X.Foo< T>> [英] BaseFoo cannot be inherited with different arguments: <T,X.Bar<T>> and <T,X.Foo<T>>

查看:154
本文介绍了BaseFoo不能用不同的参数继承:< T,X.Bar< T>>和< T,X.Foo< T>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简化版本的 Java继承流利方法在多级别层次结构中返回类型



给出以下代码:

  public enum X {
;
static interface BaseFoo< T,S扩展BaseFoo< T,S>> {
S foo();
}

静态接口Foo< T>扩展BaseFoo< T,Foo>> {
void foo1();
}

静态接口BaseBar< T,S扩展了BaseBar< T,S>>扩展BaseFoo< T,S> {
S bar();
}

静态界面Bar< T>扩展了BaseBar< T,Bar>,Foo< T> {
void bar1();
}

}

运行

  X.java:15:错误:BaseFoo不能用不同的参数继承:< T,X.Bar< T>>和< T,X.Foo< T>> 
静态界面栏< T>扩展BaseBar< T,Bar>,Foo< T> {b $ b ^

任何人都有解决方案吗?



免责声明:我试图使用该模式实施流畅的界面



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

解决方案

类或接口不能实现或扩展通用接口的不同实例。您的 Bar 界面违反了此规则。让我们来看看接口声明:

 静态接口Bar< T>扩展了BaseBar< T,Bar>,Foo< T> 

因此, Bar< T> 接口:


  • BaseBar< T,Bar< T>>

  • Foo



为此,这两个接口从相同接口 BaseFoo 的不同实例化扩展。 < / p>


  • BaseBar< T,S扩展BaseBar< T,S>>扩展BaseFoo< T,S>

  • Foo< T>扩展BaseFoo< T,Foo< T>>



这些继承的接口最终也是超级接口 Bar 界面。因此,你的 Bar 接口试图从2个不同的 BaseFoo 实例中扩展,这是非法的。使用一个简单的例子来理解原因:

  //假设这是允许的
类Demo实现Comparable< Demo> ,可比< String> {
public int compareTo(Demo arg){...}
public int compareTo(String arg){...}
}

然后在类型擦除之后,编译器会为泛型方法生成2个桥接方法。该类被翻译为:

 类Demo实现了Comparable< Demo> ,可比< String> {
public int compareTo(Demo arg){...}
public int compareTo(String arg){...}

//编译器添加的桥接方法
public int compareTo(Object arg){...}
public int compareTo(Object arg){...}
}

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


This is a simplified version of Java inherited Fluent method return type in multiple level hierarchies.

Given the following code:

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 javac X.java I get the error message:

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

Anyone has any solution?

Disclaim: I am trying to use the pattern to implement the fluent interface across a container class inheritance hierarchy.

Background: to make it easier for people to understand why I need this, here is the story. I want to create a container family: Traversal <- Sequence <- List. So Traversal has a method Traveral<T> accept(Visitor<T>) (no PECS for short), this method should always return this after iterating the visitor through the elements. When I have a List type, I want the method return List<T> instead of Traversal<T> because I want to make it possible to call something like myList.accept(v).head(15), where head(int) is a method of List not Traversal

解决方案

A class or interface cannot implement or extend from different instantiation of a generic interface. Your Bar interface is breaking this rule. Let's examine the interface declaration:

static interface Bar<T> extends BaseBar<T, Bar<T>>, Foo<T>

So, Bar<T> extends two interfaces:

  • BaseBar<T, Bar<T>>
  • Foo<T>

In addition to that, those two interfaces extend from different instantiation of the same interface BaseFoo.

  • BaseBar<T, S extends BaseBar<T, S>> extends BaseFoo<T, S>
  • Foo<T> extends BaseFoo<T, Foo<T>>

Those inherited interfaces are eventually also the super interfaces of Bar interface. Thus your Bar interface tries to extend from 2 different instantiation of BaseFoo, which is illegal. Let's understand the reason using a simple example:

// Suppose this was allowed
class Demo implements Comparable<Demo> , Comparable<String> {
    public int compareTo(Demo arg)     { ... } 
    public int compareTo(String arg) { ... } 
}

then after type erasure, compiler would generate 2 bridge methods, for both the generic method. The class is translated to:

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

So, that results in creation of duplicates bridge method in the class. That is why it is not allowed.

这篇关于BaseFoo不能用不同的参数继承:&lt; T,X.Bar&lt; T&gt;&gt;和&lt; T,X.Foo&lt; T&gt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆