具有流畅接口和继承的自定义泛型类型 [英] Self bound generic type with fluent interface and inheritance
问题描述
我正在使用带继承的流畅接口。我声明了基类Constructor受保护,所以你不能创建一个Foo< Bar>这会在调用add()时导致ClassCastException。但是我在返回新的Foo实例的静态方法时遇到了麻烦。
public class Foo< T extends Foo< T> > //如果我更改为扩展Foo,我只收到警告
{
public static Foo< Foo> createFoo()//< - error
{
return new Foo< Foo>(); //< - error
}
protected Foo(){}
public T add()
{
// ...
return(T)this;
}
}
public class Bar扩展Foo< Bar>
{
public Bar sub()
{
// ...
return this;
$ / code $ / pre
$ b $ p这主要是练习(个人不做作业)流利的接口,领域特定的语言和泛型,所以请不要问我需要它。
编辑:Eclipse错误
绑定不匹配:类型Foo不是绑定参数的有效替代< T extends Foo< T>>的类型Foo< T>
解决方案您基本上拥有递归类型声明。
Foo< T扩展Foo< T>>
。
假设你有一个 Foo< Foo>
。这意味着 T
被映射到 Foo
。但 Foo
不是 Foo< T>
的子类型,在这种情况下, Foo< Foo>
,所以你真正想要的是 Foo< Foo< Foo>>
。但等一下,最内层的 Foo
没有输入,所以我猜它是 Foo< Foo< Foo< Foo>>> code> ...哦,忘记它!
为了让它更容易理解,考虑你是否有 Foo< T extends列表与LT; T>>
。在 Foo
的声明/实例中, T
可能用于什么? 列表与LT;字符串>
? List< List>
?
编辑
看起来像你找到了一种破坏递归循环的方法。你最终需要达到一个具体化的类型。以同样的方式,你发现 ConcreteFoo
为你工作,你可以类似地为 List 上面的例子有一些类 ConreteListOfItself实现了List< ConreteListOfItself>
,这将打破递归循环。
I am using a fluent interface with inheritance. I declared the base class Constructor protected so you cant create a Foo<Bar> which would result in a ClassCastException on calling add(). But i am having trouble with the static method that returns a new Foo instance.
public class Foo<T extends Foo<T>> // if i change to extends Foo i only get warnings
{
public static Foo<Foo> createFoo() // <-- error
{
return new Foo<Foo>(); // <-- error
}
protected Foo() {}
public T add()
{
//...
return (T)this;
}
}
public class Bar extends Foo<Bar>
{
public Bar sub()
{
//...
return this;
}
}
This is mostly an excercise(personal not homework) in Fluent Interfaces, Domain-specific language and Generics, so please dont ask what i need it for.
Edit: Eclipse error
Bound mismatch: The type Foo is not a valid substitute for the bounded parameter <T extends Foo<T>> of the type Foo<T>
解决方案 You essentially have a recursive type declaration.
Foo<T extends Foo<T>>
.
So let's say you have a Foo<Foo>
. That means T
is mapped to Foo
. But Foo
is not subtype of Foo<T>
, which in this case is Foo<Foo>
, so what you're really looking for is Foo<Foo<Foo>>
. But wait a minute, the innermost Foo
isn't typed, so I guess it's Foo<Foo<Foo<Foo>>>
...oh forget it!
To put a more understandable face on it, consider if you had Foo<T extends List<T>>
. What could you possibly use for T
in a declaration/instantiation of Foo
? List<String>
? List<List>
?
Edit
It looks like you found a way to "break" the recursion cycle. You eventually need to get to a reified type. In the same way that you found that ConcreteFoo
worked for you, you could similarly for the List
example above have some class ConreteListOfItself implements List<ConreteListOfItself>
that would break the recursion cycle.
这篇关于具有流畅接口和继承的自定义泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!