Вложенные (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);
}
}
Теперь, когда экран включается, он уведомляет телефон о том, сколько электричества потребляет.