I try to implement a fluent interface in my 2D game engine.
Simplified example of my implementation:
public class Sprite<T> {
protected float x = 0.0;
protected float y = 0.0;
public T setPosition(float x, float y) {
this.x = x;
this.y = y;
return (T)this;
}
}
public class Living<T extends Living> extends Sprite<Living> {
protected boolean alive = false;
public T setAlive(boolean alive) {
this.alive = alive;
return (T)this;
}
}
public class Entity<T extends Entity> extends Living<Entity> {
protected String name = null;
public T setName(String name) {
this.name = name;
return (T)this;
}
}
Entity entity = new Entity().setPosition(100, 200).setAlive(true).setName("Zombie");
I keep getting the error: "The function setAlive(boolean) does not exist."
I know, using my methods the other way round (in a more logical order) works:
Entity entity = new Entity().setName("Zombie").setAlive(true).setPosition(100, 200);
And I know that overwriting any parent setter functions in each and every child class would work:
public class Entity extends Living {
protected String name = null;
public Entity setPosition(float x, float y) {
return (Entity)super.setPosition(x, y);
}
public Entity setAlive(boolean alive) {
return (Entity)super.setAlive(alive);
}
public Entity setName(String name) {
return (Entity)super.setName(name);
}
}
But I want the interface to be as free/uncomplicated as possible for the 'end user' and the code to be as compact and clean as it gets.
I don't know if I just messed up the generics or my hole approach is completely wrong. I hope you can help. I am open to any advice. (Sorry for my bad english.)
Edit: I already tested the following approach and it works for the Entity class.
public class Sprite<T> {
...
}
public class Living<T> extends Sprite<T> {
...
}
public class Entity extends Living<Entity> {
...
}
I forgot to mention, that I need to instantiate Sprite & Living too. For example:
Living living = new Living().setPosition(50, 50).setAlive(false);
I think your class model is over complicated, you can pass generic parameter down to the child class and then declare it explicitly:
public class Sprite<T> {
...
}
public class Living<T> extends Sprite<T> {
...
}
public class Entity extends Living<Entity> {
...
}