Javanese Online

Вложенные и внутренние классы

Вложенные (nested) классы

Телефон можно разблокировать, тогда его экран должен зажечься. Дополним интерфейс:

public interface MobilePhone extends Phone {
    int getChargePercentage();
    Screen getScreen();
    void unlock();

    interface Screen {
        // пусть у нас будет возможность проверить,
        // зажжён ли экран
        boolean isBackLightEnabled();
    }
}

Объявление interface Screen расположено прямо в теле интерфейса MobilePhone. Это вложенный интерфейс. Извне он доступен как MobilePhone.Screen.

Теперь добавим в Nokia3310 реализацию экрана. В этих телефонах используются экраны 84×48 пикселей, которые мы будем использовать только в Nokia3310, больше нам они нигде не понадобятся.

public final class Nokia3310 implements MobilePhone {

    ...
    private Lcd84x48 screen = new Lcd84x48();

    ...

    @Override
    public Screen getScreen() {
        return screen;
    }

    @Override
    public void unlock() {
        screen.enable();
    }

    private static final class Lcd84x48 implements Screen {
        private boolean backLightEnabled = false;

        void enable() {
            backLightEnabled = true;
        }

        @Override
        public boolean isBackLightEnabled() {
            return backLightEnabled;
        }
    }

}

Класс Lcd84x48 приватный — его видно только внутри класса Nokia3310. Телефон умеет зажигать экран, экран умеет зажигаться. Но экран должен потреблять энергию телефона, в котором находится. Нужно, чтобы экран «видел» телефон.

Внутренние (inner) классы

Чтобы экран имел в своём распоряжении телефон, нужно сделать вложенный класс внутренним. Для этого достаточно убрать с класса модификатор static. Тогда кроме this в классе будет виден Nokia3310.this — экземпляр внешнего класса. Так, у нас появилась возможность двустороннего общения между телефоном и его экраном.

    ...

    @Override
    public void unlock() {
        screen.enable();
    }

    void reportPowerConsumption(int consumptionMillis) {
        System.out.println("Power consumption was increased by " + 
                consumptionMillis + " mA.");
    }

    private final class Lcd84x48 implements Screen {
        private boolean backLightEnabled = false;

        void enable() {
            if (!backLightEnabled) {
                backLightEnabled = true;
                reportPowerConsumption(10);
            }
        }

Теперь, когда экран включается, он уведомляет телефон о том, сколько электричества потребляет.

Комментарии к уроку

Сообщить об ошибке

Javanese.Online в GitHub

Чаты и каналы в Telegram

RSS-лента