Шаг 48.
Язык программирования Java.
Анонимные внутренние классы

На этом шаге мы рассмотрим анонимные внутренние классы

Работая с локальными внутренними классами, можно воспользоваться еще одной интересной возможностью. Так, если требуется создать единственный объект некоторого класса, этому классу можно вообще не присваивать имени. Такой класс называется анонимным внутренним классом. Приведем ниже пример определения анонимного внутреннего класса.

public void start() {
    ActionListener listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            Date now = new Date();
            System.out.println("now " + now);
            if (beep) {
                Toolkit.getDefaultToolkit().beep();
            }
        }
    };

    Timer timer = new Timer(interval, listener);
    timer.start();
}

Следует признать, что синтаксис анонимных внутренних классов довольно сложен. На самом деле приведенный выше фрагмент кода означает следующее: создается новый объект класса, реализующего интерфейс ActionListener, где в фигурных скобках {} определен требующийся метод actionPerformed(). Ниже приведем общую форму определения анонимных внутренних классов.

new СуперТип(параметры конструирования объектов) {
	методы и данные внутреннего класса
}

Здесь СуперТип может быть интерфейсом, например ActionListener, и тогда внутренний класс реализует данный интерфейс. СуперТип может быть также классом. В этом случае внутренний класс расширяет данный суперкласс.

Анонимный внутренний класс не может иметь конструкторов, поскольку имя конструктора должно совпадать с именем класса, а в данном случае у класса отсутствует имя. Вместо этого параметры, необходимые для создания объекта, передаются конструктору суперкласса.

Следует внимательно и аккуратно проводить различие между созданием нового объекта некоторого класса и конструирование объекта анонимного внутреннего класса, расширяющего данный класс. Если за скобками со списком параметров, необходимых для создания объекта, следует открытая фигурная скобка, то определяется анонимный вложенный класс, как это показано ниже:

/*объект типа Person*/
Person queen = new Person("Mary");

/*объект внутреннего класса, расширяющего класс Person*/
Person count = new Person("Dracula") {
	...
}

Приведем исходный код завершенной версии программы, реализующей “говорящие часы”, где применяется анонимный внутренний класс.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;

/**
 * <p>Класс для тестирования программы</p>
 * */
public class AnonymousClassTest {
    public static void main(String[] args) {
        TalkingClock clock = new TalkingClock();
        clock.start(1000, true);

        JOptionPane.showMessageDialog(null, "Quit program");
        System.exit(0); /*Нужна для корректного завершения программы*/
    }
}

/**
 * <p>Класс для говорящих часов</p>
 * */
class TalkingClock {
    /**
     * <p>Функция для запуска часов</p>
     * */
    public void start(int interval, boolean beep)
    {
        Timer timer = new Timer(interval, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Date now = new Date();
                System.out.println("At the tone, the time is " + now);
                if (beep) {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        });
        timer.start();
    }
}

Проект можно взять здесь


Рис. 1. Окно сообщения


Рис. 2. Вывод программы

На следующем шаге мы рассмотрим cтатические внутренние классы

Предыдущий шаг Содержание Следующий шаг