Reputation: 462
I'm trying to make a small game with a TUI. The TUI should have a get()
method that should take a String question
and a return type as parameter, so you can use it to request an object.
For example, get("What is your name?", String)
should return a String
and get("What color do you want?", Color)
should return a Color
.
This is what I've come up with:
public interface View {
public <T> T get(String question, Class<T> type) throws InputException;
}
public class TUI implements View {
public Color get(String question, Class<Color> type) {
// code
}
public String get(String question, Class<String> type) {
// code
}
}
Color color = Game.getView().get("What piece do you want to place?", Color.class);
Unfortunately, the methods in TUI
are not accepted as implementations of public <T> T get(String question, Class<T> type) throws InputException;
. Is there any way I can do this?
Upvotes: 4
Views: 1022
Reputation: 1637
You can use something similar to Template Method Design Pattern.
public interface TypeTemplate {
public Object get(String question);
}
public class ColorTemplate implements TypeTemplate {
@Override public Color get(String question) { /*code for color*/ }
}
public class StringTemplate implements TypeTemplate {
@Override public String get() { /*code for string*/ }
}
public class TUI {
public Color get(String question, ColorTemplate templ) {
return templ.get(String question)
}
public String get(String question, StringTemplate templ) {
return templ.get(String question);
}
}
public static void main(String args[]) {
TUI tui = new TUI();
String string = tui.get("What is your name?", new StringTemplate());
Color color = tui.get("What color do you want?", new ColorTemplate());
}
You can of course replace Object
type in TypeTemplate
with something less generic. You can also make TypeTemplate
one abstract class; this way if all (or some) of your get()
methods will have to share some code you can add methods in this class and call from the subclasses. e.g.
public abstract class TypeTemplate {
public abstract Object get(String question);
protected void init() {/*some initialization code*/}
protected void cleanup(){/*some more code*/}
}
public class ColorTemplate implements TypeTemplate {
@Override
public Color get(String question) {
init();
/*code for color*/
cleanup();
}
}
public class StringTemplate implements TypeTemplate {
@Override
public String get() {
init();
/*code for string*/
cleanup();
}
}
Upvotes: 0
Reputation: 3937
Your TUI
class is not valid because under type erasure both get
methods have the same arguments.
You might want to do this:
public interface View<T> {
T get(String question, Class<T> type) throws InputException;
}
public class ColorTUI implements View<Color> {
public Color get(String question, Class<Color> type) {
// code
}
}
public class StringTUI implements View<String> {
public String get(String question, Class<String> type) {
// code
}
}
Upvotes: 0
Reputation: 259
Try to make two classes AskColor and AskString that implements View, with method respectively
public Color get(String question, Class<Color> type) {
// code
}
public String get(String question, Class<String> type) {
// code
}
and the interface View with method
public T get(String question, Class<T> type) throws InputException;
Upvotes: 0
Reputation: 195
Keeping it type safe by splitting the functions would seem more appropriate:
Color color = Game.getView().getColor("What piece do you want to place?");
String string = Game.getView().getString("What piece do you want to place?");
Upvotes: 6