Как я могу инициализировать другие классы с помощью переменной подкласса (this) в вызове метода super () в конструкторе? - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь создать библиотеку классов, которую можно будет использовать в будущих игровых проектах Swift (с минимальными корректировками кода), которые будут использоваться для создания подклассов, более специфичных для текущего проекта, над которым я работаю.Однако я столкнулся с проблемой инициализации других классов с помощью this в вызове метода super () в конструкторе.Это проблема в форме кода:

public class App extends JFrame {
    public App(AppRunner appRunner, AppPanel appPanel) {
        this.appRunner = appRunner;
        this.appPanel = appPanel;
    }
}


public class Pong extends App {
    public App() {
        super(new AppRunner(10, this), new AppPanel(this));
    }
}

Это отправляет ошибку, связанную с использованием переменной "this" до инициализации класса.

Я рассмотрел использование абстрактных методов в приложениикласс и наличие подклассов, чтобы реализовать их, но решил, что мне это не нравится.План (в кодовой форме):

public abstract class App extends JFrame {

    public App() {
        this.appRunner = initializeAppRunner();
        this.appPanel = initializeAppPanel();
    }

    abstract AppRunner initializeAppRunner();

    abstract AppPanel initializeAppPanel();
}

Я также проверил подход, используя немного обобщений и рефлексии (о которой я знаю очень мало).Мне также не нравится это, потому что я не могу изменить параметры конструктора классов очень легко.Ниже приведен мой текущий код:

public class App extends JFrame {
    public App(Class<? extends AppRunner> appRunnerClass, Class<? extends AppPanel> appPanelClass) {
        try {
            this.appRunner = appRunnerClass.getConstructor(Integer.class, App.class).newInstance(10, this);
            this.appPanel = appPanelClass.getConstructor(App.class).newInstance(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
        add(appPanel);
    }
}

public class Pong extends App {
    public Pong() {
        super(AppRunner.class, PongPanel.class);
    }
}

Думаю, мне интересно, есть ли их более простой способ сделать это или мне следует использовать пример обобщенных / абстрактных методов.

1 Ответ

0 голосов
/ 29 мая 2018

Любые проблемы, связанные с использованием:

public Pong() {
    appRunner = new AppRunner(10, this);
    appPanel = new AppPanel(this);
}

—-

Вы можете передать лямбда-функцию в конструктор приложения, что позволит вам настроить создание служебных классов, ноСуперкласс App создает эти классы.

См. Интерфейс функций .

class App extends ... {
    App( Function<App, AppRunner> runner_creator,
         Function<App, AppPanel> panel_creator) {
        appRunner = runner_creator.apply(this);
        appPanel = panel_creator.apply(this);
}

class Pong extends App {
    Pong() {
        super(
            app -> new PongRunner(10, app),
            app -> new PongPanel(app));
    }
}

Вы передаете лямбда-функцию (без каких-либо ссылок this) суперкласс, поэтому производный класс контролирует, как создаются служебные классы, и какой конкретный класс используется.

Примечание. Эти служебные классы создаются с использованием ссылки this суперклассов, которая является App, а не типом производных классов.

...