【问题标题】:Self bound generic type with fluent interface and inheritance具有流畅接口和继承的自绑定泛型类型
【发布时间】:2011-12-19 01:10:16
【问题描述】:

我正在使用带有继承的流畅接口。我声明了基类构造函数受保护,因此您不能创建一个 Foo,这会在调用 add() 时导致 ClassCastException。但是我在使用返回新 Foo 实例的静态方法时遇到了问题。

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;
        }
}

这主要是关于流畅接口、特定领域语言和泛型的练习(个人而非家庭作业),所以请不要问我需要它做什么。

编辑:Eclipse 错误

Bound mismatch: The type Foo is not a valid substitute for the bounded parameter <T extends Foo<T>> of the type Foo<T>

【问题讨论】:

  • This answer 应该有助于解释您所看到的错误的含义(特别是在粗体编辑之后)。以后请在您的问题中发布完整的错误消息。
  • 我不知道投反对票的目的是什么,我在谷歌上搜索了自绑定泛型类型,但找不到我的问题的答案。
  • @Stefan 同意,完全有效的问题。赞成反对。
  • 链接的答案实际上帮助我解决了问题。将 Foo 声明更改为:公共抽象类 AbstractFoo>。创建最终类 ConcreteFoo 扩展 AbstractFoo 没有额外的功能。然而,它确实破坏了一些继承。
  • 如果你像这样“滥用”(无意冒犯)泛型,它们真的会很痛苦。我真的是他们的朋友,但有时他们会让编写代码变得更加困难,因为没有他们。尝试声明不同的类型而不是递归结构,这很难维护和扩展。

标签: java generics inheritance fluent-interface


【解决方案1】:

你基本上有一个递归类型声明。

Foo&lt;T extends Foo&lt;T&gt;&gt;.

假设您有一个Foo&lt;Foo&gt;。这意味着T 映射到Foo。但是Foo 不是Foo&lt;T&gt; 的子类型,在这种情况下是Foo&lt;Foo&gt;,所以你真正要找的是Foo&lt;Foo&lt;Foo&gt;&gt;。但是等一下,最里面的Foo 没有输入,所以我猜是Foo&lt;Foo&lt;Foo&lt;Foo&gt;&gt;&gt;...哦算了!

为了让它更容易理解,考虑一下你是否有Foo&lt;T extends List&lt;T&gt;&gt;。在Foo 的声明/实例化中,您可以为T 使用什么? List&lt;String&gt;? List&lt;List&gt;?

编辑

您似乎找到了一种“打破”递归循环的方法。你最终需要得到一个具体化的类型。与您发现 ConcreteFoo 为您工作的方式相同,对于上面的 List 示例,您同样可以有一些 ConreteListOfItself implements List&lt;ConreteListOfItself&gt; 类,它会破坏递归循环。

【讨论】:

  • 我猜这个问题源于 Foo 没有扩展自己。
  • @Stefan:嗯,extends 在类型绑定的上下文中意味着子类类本身。所以问题不在于Foo 没有扩展Foo,问题在于Foo 没有扩展Foo&lt;Foo&gt;。就像List 没有扩展List&lt;List&gt;,但是一些子类可以。
  • 我会接受这个答案,因为它解释了为什么我试图做的事情“不起作用”。在这一点上,我认为我需要一个更强大的泛型机制,符合忽必烈所说的here,以便获得具有继承结构的流畅接口。
猜你喜欢
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
相关资源
最近更新 更多