Механизм обратного вызова(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. На экране появилось диалоговое окно.
Когда мы нажмем кнопку, или закроем диалоговое окно, сработает метод обратного вызова 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(); } }
Запускаем программу. Теперь текст сообщения в консоли меняется в зависимости от того, выберем мы да, нет или просто закроем окно.
Я надеюсь, вы поняли принцип методов обратного вызова. Ниже есть ссылка на дополнительную информацию по колбекам, а также более сложные и познавательные примеры. Вопросы можно задавать в комментариях.
<<Предыдущий урок Следующий урок>>
AndroidStudio ругается на JOptionPane. Можно ли как-то это исправить?
Аналогично… Но ответа видимо нет…