返回带泛型的对象子类

Sar*_*jot 15 java generics subclass parameterized return-type

使用抽象类,我想定义一个为子类返回"this"的方法:

public abstract class Foo {
    ...
    public <T extends Foo> T eat(String eatCake) {
        ...
        return this;
    }
}  

public class CakeEater extends Foo {}
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这样的事情:

CakeEater phil = new CakeEater();
phil.eat("wacky cake").eat("chocolate cake").eat("banana bread");
Run Code Online (Sandbox Code Playgroud)

可以说香蕉面包会抛出IllegalArgumentException,并带有"Not a cake!"的消息.

irr*_*ble 20

public abstract class Foo<T extends Foo<T>>  // see ColinD's comment
{
    public T eat(String eatCake) 
    {
        return (T)this;
    }
}

public class CakeEater extends Foo<CakeEater> 
{
    public void f(){}
}
Run Code Online (Sandbox Code Playgroud)

编辑

要求子类以某种方式行为超出静态类型可以检查的范围是没有问题的.我们一直这样做 - 简明英语的页面和页面来指定你如何编写子类.

另一个提出的解决方案,具有协变返回类型,必须做同样的事情 - 要求子类实现者,简单地说,返回类型this.静态类型无法指定该要求.

  • 是.在一个更好的世界中,Java可以有一个`This`类型,这在很多情况下非常有用. (4认同)
  • 应该是`Foo <T延伸Foo <T >>`.这很有效,但是当你调用`eat`时,你可以轻松地创建一个会被`ClassCastException`炸毁的类,例如`class Bar extends Foo <CakeEater>`. (2认同)

Tom*_*ine 17

从客户的角度来看,这种有品味的方法(通常是你想要采用的方法)是使用协变返回类型,这是为了支持泛型,正如Michael Barker所指出的那样.

稍微不那么有品味,但更有品味的演员是添加getThis方法:

protected abstract T getThis();

public <T extends Foo> T eat(String eatCake) {
    ...
    return getThis();
}
Run Code Online (Sandbox Code Playgroud)

  • @Arash它向接口添加了怪异的泛型和受保护的方法,这两者都没有品味。尽管用协变返回类型覆盖的替代方案确实会留下大量形式为“@Override public CakeEater eat(String eatCake) { super.eat(SeatCake); ”的垃圾。返回这个;}`,当基类更新时可能会错过。 (2认同)

Mic*_*ker 5

我不认为你需要泛型Java 5(及更高版本)有协变返回类型,例如:

public abstract class Foo {
    ...
    public Foo eat(String eatCake) {
        ...
        return this;
    }
}  

public class CakeEater extends Foo {

    public CakeEater eat(String eatCake) {
        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果解决方案包含`@ SuppressWarnings`,则不应将其视为解决方案.只是我的两分钱. (5认同)
  • 我认为这不是解决草图问题的一个很好的解决方案,因为它需要重写子类中的所有方法,这几乎不值得付出努力。这个想法是拥有一个流畅的 API,子类可以利用该 API,而不是重写。 (2认同)
  • 我也不认为这是需要人们忽略或压制警告的“前卫”东西 (2认同)