как создать новый неизвестный объект в абстрактном классе

#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]
 

Не уверен, насколько это полезно…