Философия Java


Замыкания & обратные вызовы


Замыкание это объект, который хранит информацию из контекста в котором он был создан. Из этого описания, Вы можете видеть, что внутренний класс замкнут на объектах, поскольку он не содержит каждый из кусочков из внешнего класса ( контекста, в котором он был создан), но он автоматически содержит ссылку на этот внешний класс, где у него есть доступ к элементам класса, даже к private.

Наиболее неоспоримым аргументом для включения можно назвать разновидность указательного механизма в Java позволяющего осуществлять обратные вызовы (callbacks). С обратным вызовом, некоторые другие объекты, могут получить кусочек информации, которая позволит им в дальнейшем передать управление в исходящий объект. Это очень мощная концепция, как Вы увидите потом, в Главе 13 и Главе 16. Если обратный вызов реализуется через использование указателя, то Вы должны очень осторожно с ним обращаться. Как Вы наверное уже могли понять, в Java имеется тенденция для более осторожного программирования, поэтому указатели не включены в этот язык.

"Замыкание" предоставляемое внутренними классами - лучшее решение, чем указатели. Оно более гибкое и намного более безопасное. Вот пример:

//: c08:Callbacks.java

// Использование внутренних классов для возврата

interface Incrementable { void increment(); }

// Очень просто реализовать интерфейс:

class Callee1 implements Incrementable { private int i = 0; public void increment() { i++; System.out.println(i); } }

class MyIncrement { public void increment() { System.out.println("Other operation"); } public static void f(MyIncrement mi) { mi.increment(); } }

// Если ваш класс должен реализовать increment() по другому,

// Вы должны использовать внутренний класс:

class Callee2 extends MyIncrement { private int i = 0; private void incr() { i++; System.out.println(i); } private class Closure implements Incrementable { public void increment() { incr(); } } Incrementable getCallbackReference() { return new Closure(); } }

class Caller { private Incrementable callbackReference; Caller(Incrementable cbh) { callbackReference = cbh; } void go() { callbackReference.increment(); } }




Начало  Назад  Вперед