Урок 13. Основы JAVA. Методы обратного вызова (callback)

Механизм обратного вызова(callbacks) широко распространен в программировании. При обратном вызове программист задает действия, которые должны выполняться всякий раз, когда происходит некоторое событие. И неважно, будете разрабатывать только java-программы или android-приложения – колбеки будут встречаться вам повсюду.

Для создания методов обратного вызова (callback) в java используются уже знакомые нам из прошлого урока интерфейсы.
Создадим новый класс SomeClass с интерфейсом Callback:
import javax.swing.*;

public class SomeClass {

// создаем колбек и его метод
    interface Callback{
        void callingBack();
    }

    Callback callback;

    public void registerCallBack(Callback callback){
        this.callback = callback;
    }

    void doSomething(){
        JOptionPane.showMessageDialog(null, "Выполняется работа");

        // вызываем метод обратного вызова
        callback.callingBack();
    }
}
У интерфейса мы определили один метод callingBack(). Далее в классе мы создали объект интерфейса и инициализировали его в методе registerCallBack. В классе также был создан метод doSomething(), в котором может содержаться какой-то сложный код. Мы здесь создаем диалоговое окно, используя компонент JOptionPane библиотеки Swing. Кто не в курсе, Swing — библиотека для создания графического интерфейса программ на языке Java.
В конце работы метода doSomething() вызывается метод интерфейса callingBack() . В данном случае мы сами создали метод и знаем его код. Но во многих случаях, вы будете использовать готовый метод какого-то класса и можете даже не знать, что именно содержится в этом методе. Вам надо только знать, что такой метод существует и выполняет конкретную задачу.
Теперь нам нужен класс, реализующий интерфейс-callback. Создаем класс MyClass и  подключаем интерфейс-колбек через ключевое слово implements. Среда разработки заставит нас реализовать шаблон метода интерфейса.
public class MyClass implements SomeClass.Callback {

    @Override
    public void callingBack() {

        System.out.println("Вызов метода обратного вызова");

    }
}
Теперь мы можем использовать метод обратного вызова callingBack () для решения своих задач. Будем здесь выводить текст в консоль. Создадим класс Main, в котором будет реализован метод main – точка входа в программу.
public class Main {

    public static void main(String[] args) {
        SomeClass someClass = new SomeClass();
        MyClass myClass = new MyClass();

//инициализируем колбек, передавая методу registerCallBack экземпляр MyClass, реализующий интерфейс колбек
        someClass.registerCallBack(myClass);
        someClass.doSomething();

    }
}
Здесь создаем экземпляры классов, инициализируем колбек, передавая методу registerCallBack экземпляр MyClass, реализующий интерфейс-callback. И вызываем метод doSomething();
При старте программы будет выполняться код метода doSomething(); из класса SomeClass.  На экране появилось диалоговое окно.
2016-06-28_19-17-36
Когда мы нажмем кнопку, или закроем диалоговое окно,  сработает метод обратного вызова callingBack(), который выведет сообщение в консоль.
Через интерфейс-callback также можно передавать какие-то данные. Давайте немного усложним пример.
package callback;

import javax.swing.*;

public class SomeClass {

    String replyTo;

    interface Callback{
        void callingBack(String s);
    }

    private Callback callback;

    public void registerCallBack(Callback callback){
        this.callback = callback;
    }

    void doSomething(){
       int reply = JOptionPane.showConfirmDialog(null, "Вы программист?", "Опрос", JOptionPane.YES_NO_OPTION);

        if (reply == JOptionPane.NO_OPTION){
            replyTo = "Нет";
        }
        if (reply == JOptionPane.YES_OPTION){
            replyTo = "Да";
        }

        callback.callingBack(replyTo);
    }
}
Объявим строковую переменную replyTo. Добавим аргумент метода callingBack – строковую переменную.
Изменим диалоговое окно – присвоим его новой целочисленной переменной reply, и изменим на showConfirmDialog, который имеет заголовок окна и больше одной кнопки ответа. В зависимости от нажатой кнопки переменной reply будет присвоено значение. Сравниваем ее значение с константой и присваиваем значение “Да” или “Нет” переменной replyTo.
Теперь внесем изменения в MyClass.
package callback;

public class MyClass implements SomeClass.Callback {
    @Override
    public void callingBack(String s) {

        if (s != null) {
            System.out.println("Ваш ответ: " + s);
        } else {
            System.out.println("Вы не ответили на вопрос!");
        }
    }
}
Добавим аргумент в метод. И добавим условие проверки, что строка не пустая – это возможно, если  вместо ответа просто закрыть диалоговое окно.
Класс Main без изменений.
package callback;


public class Main {

    public static void main(String[] args) {

        SomeClass someClass = new SomeClass();
        MyClass myClass = new MyClass();

        someClass.registerCallBack(myClass);
        someClass.doSomething();
    }
}
Запускаем программу. Теперь текст сообщения в консоли меняется в зависимости от того, выберем мы да, нет или просто закроем окно.
2016-06-28_19-13-28
Я надеюсь, вы поняли принцип методов обратного вызова. Ниже есть ссылка на  дополнительную информацию по колбекам, а также более сложные и познавательные примеры. Вопросы можно задавать в комментариях.

Примеры методов обратного вызова (callbacks)


<<Предыдущий урок     Следующий урок>>

Коментарі: 3
  1. AndroidStudio ругается на JOptionPane. Можно ли как-то это исправить?

    1. iamserj61@gmail.com

      Аналогично… Но ответа видимо нет…

Додати коментар