Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an objects subclass with generics

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!"

like image 619
Sarabjot Avatar asked Jul 19 '10 20:07

Sarabjot


People also ask

Is it possible to return a generic type in Java?

(Yes, this is legal code; see Java Generics: Generic type defined as return type only.) The return type will be inferred from the caller.

Can an object be a return type?

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.

Can you return an abstract class in Java?

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.


1 Answers

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.

like image 111
irreputable Avatar answered Sep 28 '22 12:09

irreputable