java 使用泛型返回对象子类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3284610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning an objects subclass with generics
提问by Sarabjot
With an abstract class I want to define a method that returns "this" for the subclasses:
使用抽象类,我想定义一个为子类返回“this”的方法:
public abstract class Foo {
...
public <T extends Foo> T eat(String eatCake) {
...
return this;
}
}
public class CakeEater extends Foo {}
I want to be able to do things like:
我希望能够做这样的事情:
CakeEater phil = new CakeEater();
phil.eat("wacky cake").eat("chocolate cake").eat("banana bread");
Arguably banana bread would throw an IllegalArgumentException with the message "Not a cake!"
可以说香蕉面包会抛出 IllegalArgumentException 并显示消息“不是蛋糕!”
回答by irreputable
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.
另一个建议的解决方案,具有协变返回类型,必须做同样的事情——用简单的英语要求子类实现者返回this. 静态类型不能指定该要求。
回答by Tom Hawtin - tackline
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.
正如 Michael Barker 指出的那样,从客户端的角度(通常是您想要采用的方法)来看,一种有品味的方法是使用协变返回类型,该类型被添加以支持泛型。
The slightly less tasteful, but more tasteful that a cast is to add a getThismethod:
稍微不那么有品味,但更有品味的演员是添加一个getThis方法:
protected abstract T getThis();
public <T extends Foo> T eat(String eatCake) {
...
return getThis();
}
回答by Michael Barker
I don't think you need generics Java 5 (and later) has covariant return types, e.g.:
我认为您不需要泛型 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;
}
}
回答by CurtainDog
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.
我以前用来实现类似行为的一种方法是让子类将其类型传递给(泛化的)父类型的构造函数。作为免责声明,我是动态生成子类的,继承有点欺骗,以保持我的代码生成简单,一如既往,我的第一直觉是尝试完全删除扩展关系。

