— Итак, тема номер два – вложенные классы.
Перед объявлением внутреннего класса мы можем поставить ключевое слово – static и тогда внутренний класс станет вложенным.
Давай разберемся, что же значит слово static рядом с объявлением вложенного класса. Как ты думаешь?
— Если переменная объявлена статической, то она существует в единственном экземпляре, а если вложенный класс – статический, то можно создать всего один объект такого класса?
— Пусть слово static тут не вводит тебя в заблуждение. Если переменная объявлена статической – то она существуют в единственно экземпляре – это верно. Но статический вложенный класс больше похож на статический метод в этом плане. Слово static перед объявлением класса указывает, что этот класс не хранит в себе ссылок на объекты внешнего класса, внутри которого объявлен.
— Ага. Обычные методы втихаря хранят ссылку на объект, а статические – нет. То же и со статическими классами, я прав, Элли?
— Абсолютно. Твоя догадливость очень похвальна. Вложенные статические классы не имеют скрытых ссылок на объекты внешнего класса, в котором они объявлены.
class Zoo
{
private static int count = 7;
private int mouseCount = 1;
public static int getAnimalCount()
{
return count;
}
public int getMouseCount()
{
return mouseCount;
}
public static class Mouse
{
public Mouse()
{
}
public int getTotalCount()
{
return count + mouseCount; //ошибка компиляции.
}
}
}
Давай посмотрим внимательно на этот пример.
К каким переменным может обращаться статический метод getAnimalCount?
— Только к статическим. Это же статический метод.
К каким переменным может обращаться метод getMouseCount?
— И к статическим, и к нестатическим. Он скрытно хранит ссылку(this) на объект типа Zoo.
— Верно. Так вот, статический вложенный класс Mouse, как и статический метод, может обращаться к статическим переменным класса Zoo, но не может обращаться к нестатическим.
Мы можем спокойно создавать объекты класса Mouse, даже когда нет ни одного созданного объекта класса Zoo. Вот как можно это сделать:
class Home
{
public static void main(String[] args)
{
Zoo.Mouse mouse = new Zoo.Mouse();
}
}
Фактически класс Mouse – это самый обычный класс. Из-за того, что он объявлен внутри класса Zoo, у него есть две особенности.
1) При создании объектов вложенного класса (как класс Mouse) вне внешнего класса-родителя, надо еще указывать через точку и имя внешнего класса.
Например так: Zoo.Mouse.
2) Класс Zoo.Mouse и его объекты имеют доступ к private static переменным и методам класса Zoo ( класс Mouse ведь тоже объявлен внутри класса Zoo).
На этом на сегодня все.
— Т.е. просто дополнительное имя и все?
Да.
— Это еще проще, чем казалось на первый взгляд.