返回带有泛型的对象子类

发布于 2024-09-10 05:19:55 字数 367 浏览 6 评论 0原文

对于抽象类,我想定义一个为子类返回“this”的方法:

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

public class Eater extends Foo {}

我希望能够执行以下操作:

Eater phil = new Eater();
phil.eat("wacky cake").eat("chocolate cake").eat("banana bread");

With an abstract class I want to define a method that returns "this" for the subclasses:

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

public class Eater extends Foo {}

I want to be able to do things like:

Eater phil = new Eater();
phil.eat("wacky cake").eat("chocolate cake").eat("banana bread");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

漆黑的白昼 2024-09-17 05:19:55
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(){}
}

编辑

要求子类以某种超出静态类型可以检查的方式运行是没有问题的。我们一直这样做——用一页又一页的简单英语来指定如何编写子类。

另一种提出的具有协变返回类型的解决方案必须执行相同的操作 - 用简单的英语要求子类实现者返回 this 的类型。该要求无法通过静态类型来指定。

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

Edit

There is no problem to require subclass behave in a certain way that's beyond what static typing can check. We do that all the time - pages and pages of plain english to specify how you write a subclass.

The other proposed solution, with covariant return type, must do the same - asking subclass implementers, in plain english, to return the type of this. That requirement cannot be specified by static typing.

孤星 2024-09-17 05:19:55

从客户端的角度来看(通常是您想要采用的方法),一种有品味的方法是使用协变返回类型,该类型是为了支持泛型而添加的,正如 Michael Barker 指出的那样。

稍微没那么有品味,但更有品味的强制转换是添加一个 getThis 方法:

public abstract class Foo<T extends Foo<T>> {
    protected abstract T getThis();

    public T eat(String eatCake) {
        ...
        return getThis();
    }
}

public class CakeEater extends Foo<CakeEater> {
    @Override protected CakeEater getThis() {
        return this;
    }
}

The tasteful approach from the client point of view (which is usually the one you want to take) is to use covariant return types which was added to support generics, as Michael Barker points out.

The slightly less tasteful, but more tasteful that a cast is to add a getThis method:

public abstract class Foo<T extends Foo<T>> {
    protected abstract T getThis();

    public T eat(String eatCake) {
        ...
        return getThis();
    }
}

public class CakeEater extends Foo<CakeEater> {
    @Override protected CakeEater getThis() {
        return this;
    }
}
人心善变 2024-09-17 05:19:55

我认为你不需要泛型 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;
    }
}

I don't think you need generics Java 5 (and later) has covariant return types, e.g.:

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

public class CakeEater extends Foo {

    public CakeEater eat(String eatCake) {
        return this;
    }
}
计㈡愣 2024-09-17 05:19:55

我之前使用过的实现类似行为的方法是让子类将其类型传递到(泛化的)父类型的构造函数中。作为免责声明,我正在动态生成子类,而继承对于保持代码生成简单来说有点作弊,因为我的第一直觉总是尝试完全删除扩展关系。

An approach I've used before to achieve similar behaviour is to have the subclass pass its type into a constructor of the (generified) parent type. By way of disclaimer I was generating the subclasses on the fly and inheritence was a bit of a cheat to keep my code generation simple, as always my first instinct is to try to remove the extends relationship altogether.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文