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.静态类型无法指定该要求.
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)
我不认为你需要泛型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)