#java #abstract-class #builder-pattern
#java #абстрактный класс #конструктор-шаблон
Вопрос:
Я хотел бы использовать шаблон builder для создания неизвестного объекта
как это сделать?
мой код выглядит так:
public abstract class abstractA<T extends GameApplication<T>>{
public static class Builder<T> {
private JPanel panel = new JPanel();
private JFrame frame = new JFrame();
private int height = 0, width = 0;
private int x = 0,y = 0;
private Color backgroundColor = Color.BLUE;
public Builder setFrameHeightWidth(int height, int weight) {
this.height = height;
this.width = weight;
return this;
}
public Builder setLocation(int x, int y) {
this.x = x;
this.y = y;
return this;
}
public Builder setbackground(Color color) {
this.backgroundColor = color;
return this;
}
public T Build(){
//error here
return new T ;
}
}
Я хочу использовать его следующим образом:
class RealA extends abstractA{
public static void main(String[] argv){
RealA a = abstractA.builder
.setLocation(100,200)
.setFrameHeightWidth(500,600)
.build();
}
}
и я не могу создать универсальный объект, но мне это нужно. Как это сделать?
Комментарии:
1. Вы не можете. Из-за стирания типа фактический тип
T
неизвестен во время выполнения.2. Откуда вы вообще знаете, что
T
у него есть 5 свойств, которые собрал ваш конструктор. Переосмыслите, что вы пытаетесь сделать.
Ответ №1:
Вы можете сделать (что-то вроде) этого, если вы сообщите разработчику, что он создает (передав ему класс), а затем заставить его создать экземпляр с использованием отражения (например newInstance
, метод classes ).
Предполагается, что все подклассы имеют конструктор с нулевым аргументом. (Его можно изменить, чтобы использовать конструктор с аргументами, но для каждого подкласса потребуется конструктор с той же сигнатурой)
Например…
public class Stack {
static abstract class Common {
protected String name;
public void setName(String name) {
this.name = name;
}
public abstract void doSomething();
}
static class Solid1 extends Common {
@Override
public void doSomething() {
System.out.println("Solid1's implementation: name=" name);
}
}
static class Solid2 extends Common {
@Override
public void doSomething() {
System.out.println("Solid2's implementation: name=" name);
}
}
static class Builder<T extends Common> {
private final Class<T> clazz;
private String name;
public Builder(Class<T> clazz) {
this.clazz = clazz;
}
public Builder<T> setName(String name) {
this.name = name;
return this;
}
public T build() {
T t;
try {
t = clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException("Bad things have happened!");
}
t.setName(name);
return t;
}
}
public static void main(String[] args) {
Solid1 solid1 = new Builder<>(Solid1.class).setName("[NAME]").build();
Solid2 solid2 = new Builder<>(Solid2.class).setName("[NAME]").build();
solid1.doSomething();
solid2.doSomething();
}
}
Вывод…
Solid1's implementation: name=[NAME]
Solid2's implementation: name=[NAME]
Не уверен, насколько это полезно…