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 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!"
(Yes, this is legal code; see Java Generics: Generic type defined as return type only.) The return type will be inferred from the caller.
User-defined functions and class methods can define return types as object references (as class or interface types). When an object is passed locally, class instances are always returned by reference. Thus, only a reference to an object is returned, not the object itself.
You can return an abstract class. There's no law about returning interfaces or abstract classes, it depends on your software design: One way to to return your x , y , z is to use the Factory Pattern. If you don't want to use condition then you can use a Builder pattern to do what @JVerstry posted.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With