Java наследование абстрактного класса путем объявления новых методов - PullRequest
0 голосов
/ 07 июля 2019

В моем андроид-проекте у меня есть абстрактный класс Request

package Managers;

import java.util.HashMap;

public abstract class Request {
    public interface Completion {
        void execute(HashMap<String, Object> result);
    }

    protected Completion completion;
    protected HashMap<String, Object> requestResult;

    public void setCompletion(Completion newCompletion) {
        completion = newCompletion;
        if (requestResult != null) {
            completion.execute(requestResult);
            requestResult = null;
        }
    }
}

И в моем классе RequestsManager я создал его примерно так:

public static Request numberAvailabilityCheck = new Request() {
    public String isSuccess = "isSuccess";
    public String result = "result";

    public void sendRequest(String number) {
        new java.util.Timer().schedule(new java.util.TimerTask() {
            @Override
            public void run() {
                requestResult = new HashMap<String, Object>();
                requestResult.put(isSuccess, true);
                requestResult.put(result, true);
                if (completion != null) {
                    completion.execute(requestResult);
                    requestResult = null;
                }
            }
        }, 5000);
    };
};

В моем классе MainFragment мне нужно использоватьnumberAvailabilityCheck вроде так

private View.OnClickListener checkEventListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RequestsManager.numberAvailabilityCheck.setCompletion(numberAvailabilityCheckCompletion);
        ViewRelatedUtils.closeKeyboard(getActivity());
        isProcessingCheckNumber = true;
        showProcessing();
        RequestsManager.numberAvailabilityCheck.sendRequest(numberField.getText());
    }
};

Но компилятор не видит метод RequestsManager.numberAvailabilityCheck.sendRequest в MainFragment.Почему компилятор этого не видит?Что понимает компилятор, когда я так объявляю открытый метод sendRequest в RequestsManager?И как я могу заставить компилятор увидеть это?

Ответы [ 2 ]

2 голосов
/ 07 июля 2019

Обратите внимание, что ваш код может без проблем вызывать метод setCompletion ()!

Этот метод определен для вашего базового класса. Другой метод определен только в рамках вашего экземпляра анонимного внутреннего класса! Поэтому компилятор не «видит» его и не дает вам вызвать его!

Обратите внимание: если бы вы могли как-то превратить это поле в локальную переменную, объявленную без типа (с помощью нового ключевого слова var в Java 10), ваш код работал бы: компилятор может определить тот факт, что вы добавили этот метод , Но, объявив этот объект типа Request, компилятор может только сказать вам, что этот метод не существует.

Но использование var не является хорошим подходом, вместо этого может быть решение: добавьте абстрактный метод для sendRequest () в ваш класс Request! Если это невозможно, подумайте о том, чтобы не использовать один абстрактный базовый класс, почему бы не иметь дополнительные абстрактные классы, расширяющие ваш базовый класс, каждый из которых предоставляет немного другой метод send.

0 голосов
/ 07 июля 2019

Спасибо всем за описание, почему компилятор не видит метод.Я нашел решение, которое, я думаю, является наиболее удобным для меня.В RequestsManager я объявил открытый класс NumberAvailabilityCheck, который расширяет Request и общедоступный статический член этого класса numberAvailabilityCheck.

public static class NumberAvailabilityCheck extends Request {
    public String isSuccess = "isSuccess";
    public String result = "result";

    public void sendRequest(String number) {
        new java.util.Timer().schedule(new java.util.TimerTask() {
            @Override
            public void run() {
                requestResult = new HashMap<String, Object>();
                requestResult.put(isSuccess, true);
                requestResult.put(result, true);
                if (completion != null) {
                    completion.execute(requestResult);
                    requestResult = null;
                }
            }
        }, 5000);
    };
};
public static NumberAvailabilityCheck numberAvailabilityCheck = new NumberAvailabilityCheck();

Обратите внимание, что NumberAvailabilityCheck не может быть объявлено как личное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...