Сохранение переменной как подкласса (интерфейс) - PullRequest
0 голосов
/ 18 января 2019

Я делаю расширение AsyncTask, которое связывается со службой с помощью различных действий и возвращает разные типы результатов в зависимости от используемого действия.У каждого действия есть слушатель, состоящий из интерфейсов, расширяющих один интерфейс с именем OnCommunicationFailedListener.Дело в том, что я хочу иметь только одну переменную для сохранения прослушивателя типа OnCommunicationFailedListener и сделать так, чтобы пользователь мог сохранять все «подинтерфейсы» в этой переменной.Они могут сохранять их как есть, но я не могу вызвать методы, которые вводит «подинтерфейс».

class CommunicationTask extends AsyncTask<Void, Void, String> {
    private Action action;  
    private OnCommunicationFailedListener listener;

    enum Action {
        LOGIN,
        LOGOUT,
        SEARCH
    }

    interface OnCommunicationFailedListener {
        void onCommunicationFailed();
    }

    interface OnLoginAchievedListener extends OnCommunicationFailedListener {
        void onLoggedIn(String result);
        void onLoginError(String error);
    }

    interface OnLogoutAchievedListener extends OnCommunicationFailedListener {
        void onLoggedOut(String result);
        void onLogoutError(String error);
    }

    interface OnSearchAchievedListener extends OnCommunicationFailedListener {
        void onSearchAchieved(String[] results);
    }

    @Override protected String doInBackground(Void... voids){
        try {
            // Try to communicate with a query, resulting in some result.
            return result;
        } catch(IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override protected void onPostExecute(String result){
        super.onPostExecute(result);

        if(result == null) {
            listener.onCommunicationFailed();
            return;
        }

        // ALL OF THESE GIVE ERRORS, SINCE THE METHODS DO NOT EXIST ANYMORE
        switch(action){
            case LOGIN:
                if(<check if result is ok>){
                    listener.onLoggedIn(result);
                } else listener.onLoginError(<some error>);
                break;

            case LOGOUT:
                if(<check if result is ok>){
                    listener.onLoggedOut(result);
                } else listener.onLogoutError(<some error>);
                break;

            case SEARCH:
                String[] results = <process result>;
                listener.onSearchAchieved(results);
                break;
        }
    }

    void login(String user, String password, OnLoginAchievedListener listener){
        this.listener = listener;
        action = Action.LOGIN;

        //Build the query...

        execute();
    }

    void logout(OnLogoutAchievedListener listener){
        this.listener = listener;
        action = Action.LOGOUT;

        //Build the query...

        execute();
    }

    void search(String query, OnSearchAchievedListener listener){
        this.listener = listener;
        action = Action.SEARCH;

        //Build the query...

        execute();
    }
}

Идея состоит в том, что другой класс вызывает методы login(), logout() или search() и дает им слушателя типа действия.Когда связь завершена и результат получен, вызываются методы слушателя действия (в моем коде это происходит в операторе switch).

Дело в том, что эти методы не могут быть вызваны с момента передачислушатель был приведен к OnCommunicationFailedListener.

Есть ли способ сохранить подкласс в переменной его типа суперкласса, не будучи приведенным к нему?Я не хочу иметь фактические переменные для каждого типа слушателя.

...