1. Внутренние классы

Недавно вы узнали, что бывают статические переменные и статические методы, но, оказывается, бывают еще и статические классы. Но начнем немного издалека.

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

class ВнешнийКласс
{
   переменные класса
   методы класса

   class ВнутреннийКласс
   {
      переменные класса
      методы класса
   }
}

Просто объявляем один класс внутри другого — и все.

Пример:

public class Solution
{
   static ArrayList<Point> points = new ArrayList<Point>();

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}

Внутренние классы бывают статические и нестатические. Статические классы еще называют вложенными (static nested class), нестатические просто называют внутренними классами (inner class).


undefined
13
Задача
Java Syntax Pro, 13 уровень, 2 лекция
Недоступна
Плата по счетам
В классе Solution есть поле balance, которое описывает баланс средств на банковском счете. При объявлении проинициализируй его значением Integer.MAX_VALUE. Реализуй метод processPayment(String), который принимает чек и производит списание средств со счета соответственно чеку. Метод main не принимает

2. Статические классы

Статические вложенные классы можно использовать вне своего родительского класса. Если у такого класса стоит модификатор доступа public, его можно использовать в любом месте программы. Такие классы фактически ничем не отличаются от любого обычного класса. Хотя есть пара отличий.

Имя класса

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

КлассРодитель.ВложенныйКласс

Примеры:

Класс родитель Вложенный класс Полное имя вложенного класса
com.javarush.Solution
Point
com.javarush.Solution.Point
java.util.Map
Entry
java.util.Map.Entry
java.util.Files
DirectoryStream
java.util.Files.DirectoryStream
java.nio.WindowsPath
Closeable
java.nio.WindowsPath.Closeable

Если вложенный класс имеет свой вложенный класс, их имена просто склеиваются через точку.

Типичный пример вложенного класса в JDK — это класс Entry внутри класса Map. Если вы хотите получить множество пар элементов из объекта HashMap, то метод entrySet() вернет вам множество пар типа Set<Map.Entry>.

Вот запись Map.Entry — это и есть внешний и внутренний классы.

Создание объекта

Создать объект вложенного статического класса очень легко. Выглядит это так:

КлассРодитель.ВложенныйКласс имя = new КлассРодитель.ВложенныйКласс();

Все, как и с обычными классами, только имя двойное.

Обращение к статическим методам

Если у статического класса есть статические методы, обращаться к ним можно точно так же, как к статическим методам обычных классов (только имя класса теперь двойное).

КлассРодитель.ВложенныйКласс.статическийМетод();

Обращение к статическим переменным

Обращаться к публичным статическим переменным вложенного класса тоже легко:

КлассРодитель.ВложенныйКласс.имяСтатическойПеременной

undefined
13
Задача
Java Syntax Pro, 13 уровень, 2 лекция
Недоступна
Метод деления
Реализуй метод divide(double a, double b) так, чтобы в консоли выводился результат деления числа a на число b. Должно выводиться следующее значение: 1. Double.POSITIVE_INFINITY, если верен любой из следующих пунктов: - a положительное и b равно 0; - a равно Double.POSITIVE_INFINITY и b >= 0; - a

3. Особенности статических классов

Статические внутренние классы меньше всего стоило бы называть статическими. Они ведут себя точно так же, как обычные классы. Никаких ограничений на обращение к ним из нестатических методов нет.

Если вы работаете с внутренним статическим классом внутри его класса-родителя, вообще не заметите никакой разницы с тем, если бы этот внутренний класс был бы самым обычным классом (не вложенным и не статическим).

Пример:

Внутренний статический класс Point Обычный класс Point
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }
}

class Point
{
   int x;
   int y;
}

Если вы возьмете какой-то вложенный статический класс и вынесете его из его класса родителя, все, что изменится, так это то, что новый класс потеряет способность обращаться к private static переменным и методам бывшего класса-родителя.

Пример:

Внутренний статический класс Point Обычный класс Point
public class Solution
{
   private static ArrayList<Point> points;

   static class Point
   {
      int x;
      int y;

      public static void main(String[] args)
      {
         Point point = new Point();
         point.x = 100;
         point.y = 200;

         // будет работать
         points = new ArrayList<Point>();
         points.add(point);
      }
   }
}
public class Solution
{
   private static ArrayList<Point> points;
}

class Point
{
   int x;
   int y;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;

      // тут будет ошибка
      points = new ArrayList<Point>();
      points.add(point);
   }
}

Метод main в обычном классе Point не может обращаться к private static переменной points класса Solution!

Это, собственно, и есть главное отличие вложенного статического класса от обычного класса. Методы вложенного статического класса имеют доступ ко всем статическим переменным и методам своего класса родителя, даже если те объявлены private.

Ну а если разобраться, что тут удивительного? Модификатор private прямо говорит, что к переменным и методам, обозначенным этим модификатором, можно обращаться только изнутри их класса. Внутренний статический класс находится внутри класса-родителя? Да, тогда никаких проблем: обращайтесь сколько хотите.


undefined
13
Задача
Java Syntax Pro, 13 уровень, 2 лекция
Недоступна
Анализ строк
Реализуй методы countDigits(String), countLetters(String), countSpaces(String), которые должны возвращать количество цифр, букв и пробелов в строке. Метод main не принимает участия в проверке.
undefined
13
Задача
Java Syntax Pro, 13 уровень, 2 лекция
Недоступна
Какое число меньше
Программа сравнивает два числа. Если первое число меньше второго, то в консоль выводится сообщение: Первое число меньше второго. Если первое число больше второго или равно второму числу, то в консоль выводится сообщение: Первое число больше или равно второму числу. Но на данный момент программа заве
undefined
13
Задача
Java Syntax Pro, 13 уровень, 2 лекция
Недоступна
Сравнение символов
Метод compare(Character, Character) принимает два символа, выводит в консоли результат их сравнения. Реализуй метод compare(Character, Character), который должен правильно сравнивать символы. Если код первого символа больше второго, вывести "больше". Если код первого символа меньше второго, вывести