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

В Java определены вложенные классы. Вложенным называется такой класс, который объявляется в другом классе.

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

Существуют два типа вложенных классов. Одни вложенные классы объявляются с помощью модификатора доступа **static**, а другие - без него. Нестатический вариант вложенных классов называются **внутренними**.

Внутренние классы позволяют вам группировать классы, логически принадлежащие друг другу, и управлять доступом к ним. Однако важно понимать, что внутренние классы заметно отличаются от композиции.

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

### Создание внутренних классов

Создать внутренний класс несложно - достаточно разместить определение класса внутри окружающего класса.

```java
public class Main {

    public static void main(String[] args) {
        Parcel parcel = new Parcel();
        parcel.ship("Лимпопо");
    }
}

class Parcel {

    class Contents {
        private int i = 11;
        public int value() {return i;}
    }
    
    class Destination {
        private String label;

        public Destination(String label) {
            this.label = label;
        }

        public String getLabel() {
            return label;
        }
    }
    
    public void ship(String destination) {
        Contents c = new Contents();
        Destination d = new Destination(destination);
        System.out.println(d.getLabel());
    }
}
```

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

Иногда внутренний класс используется для предоставления ряда услуг внешнему классу, в котором он содержится.

```java
public class Outer {

    private List<Integer> numbers = new ArrayList<>();

    public void printAnalyticalData() {
        Inner inner = new Inner();

        System.out.println("Min: " + inner.min());
        System.out.println("Max: " + inner.max());
        System.out.println("Sum: " + inner.sum());
    }

    private class Inner {
        private int min() {
            return numbers.stream().min(Integer::compareTo).orElse(0);
        }

        private int max() {
            return numbers.stream().max(Integer::compareTo).orElse(0);
        }

        private int sum() {
            return numbers.stream().reduce(Integer::sum).orElse(0);
        }
    }
}
```

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

```java
public class Main {
    public static void main(String[] args) {
        
        class Local {
            private int value;

            private Local(int value) {
                this.value = value;
            }
        }
        
        Local local = new Local(10);
    }
}
```

Также внутренний класс можно быть анонимным классом (анонимные классы уже были рассмотрены ранее).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://opu.gitbook.io/oop/2019-2020-archive/arkhiv-1/arkhiv/lekcii/blok-lekcii-5-1/untitled-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
