Class
    
    
        Основные разделы
        Виды классов
        
        О классах
        
    
    
        Class
        Class - обычный класс для создания объектов.
    
    
        Абстрактный класс(Abstract Class)
        Абстрактный класс(Abstract Class) - Для описания того из чего нельзя создать объект(например мебель).
            Могут иметь абстракт методы и реализации. Наследование возможно только от одного класса.
        
    
    
        Record(since v.14)
        Record - immutable класс для хранения записей.
        Не может использовать extends, но может имплементировать implements.
        
record Point(int x, int y) { }
        
        Описание
        
            - Авто создание конструктора для всех полей.
- Авто создание getters для всех полей, но без префикса get.
- Авто реализация метода equals.
- Авто реализация метода hashCode.
- Авто реализация метода toString.
- Можно добавлять статические поля и методы.
Можно описывать конструктор вручную
        
public Person(String name) {
    this(name, "Unknown");
}
        
    
    
        Внутренние классы
        Примечание - при создании нескольких классов в одном файле. С доступом public может быть
            только один. Тот который соответствует имени файла. Или ошибка компиляции.
        
        Nested Inner classes(вложенные внутренние классы)
        Создание объекта: Outer.Inner inner = new Outer().new Inner();
        Static Nested classes or Member of outer class (статические вложенные классы)
        Anonymous Inner classes (анонимные классы)
        
interface AnimalActions {
    void eat();
}
AnimalActions animal = new AnimalActions() {
    @Override
    public void eat() {
        System.out.println("Animal %s eating...");
    }
};
animal.eat();
        
        Method Local Inner classes (внутренние классы в локальном методе)
    
    
        Интерфейс(Interface)
        Интерфейс(Interface) - специальный класс-контракт для добавления функционала в другие классы.
        
            - Может иметь default methods(since v.8).
- Может иметь private methods(since v.9).
- Поля только public static final.
- Возможно имплементировать несколько интерфейсов.
Enum(Перечисления)
        Enum(перечисление) - это набор логически связанных констант именованных констант. Все константы пишутся
            большими буквами.
        Возможности:
        
            - Может иметь конструктор(только private).
- Может иметь методы, в том числе скрытые и абстрактные.
- Может переопределять общий метод описанный в Enum в отдельных константах.
- Может реализовывать интерфейс.
- Можно использовать в операторе switch.
Методы
        
            - values() - возвращает массив, содержащий список всех констант перечисления.
- valueOf() - возвращает константу перечисления, значение которой передается строкой при вызове.
- equals() - сравнивает эквивалентность.
Примеры
        Пример создания простого Enum
        
enum Cat {
    LEOPARD, PUMA, LION, TIGER, MANUL
}
        
        Пример использования
        
Cat a = Cat.PUMA;
        
        Пример создания Enum c полем и переопределенным методом в отдельной константе
        
enum SideOfWorld {
    NORTH("up") {
        void findTheBoss() {
            System.out.println("Santa is here!");
        }
    },
    SOUTH("down"),
    EAST("left"),
    WEST("right");
    private String direction;
    SideOfWorld(String direction) {
        this.direction = direction;
    }
    public String getDirection() {
        return direction;
    }
    void findTheBoss() {
        System.out.println("There is nobody!");
    }
        
        Пример использования
        
SideOfWorld sow = SideOfWorld.NORTH;
SideOfWorld sow1 = SideOfWorld.SOUTH;
sow.findTheBoss();
sow1.findTheBoss();
        
    
    
        Части класса
        
            - Импорты
- Аннотации
- Поля
- Методы
- Конструкторы
- Объекты
- Блок инициализации - блок кода внутри класса, который выполняется каждый раз при создании нового
                экземпляра класса. Используется для инициализации нестатических переменных. В них можно вызывать
                методы.
            
- Статический Блок инициализации - - отличается словом static. Используется для инициализации статических
                переменных. В них можно выполнять методы.
            
- Внутренние классы.
Порядок инициализации класса
        
            - Статические блоки и статические поля в порядке объявления суперкласса(А)
- Статические блоки и статические поля в порядке объявления подкласса(В)
- Не статические блоки и не статические поля в порядке объявления суперкласса(А)
- Конструктор суперкласса(А)
- Не статические блоки и не статические поля в порядке объявления подкласса(B)
- Конструктор подкласса(B)
Пример
        
            - static field parent
- static { } parent
- static field child
- static { } сhild
- non static field parent
- non static { } parent
- constructor parent
- non static field child
- non static { } child
- constructor child
Sealed классы/интерфейсы
        Модификатор final в классе не позволяет никому расширить его. Ключевое слово sealed позволяет расширить
            класс, но разрешить это только для указанных классов.
        
        
public sealed class Vehicle permits Bicycle, Car {...}
//and use it
public final class Bicycle extends Vehicle {...}
        
        Ограничения
        
            - Разрешенные подклассы должны быть доступны запечатанному классу во время компиляции.
- Разрешенные подклассы должны напрямую расширять запечатанный класс
- Разрешенные подклассы должны иметь один из следующих модификаторов:final, sealed, non-sealed
- Разрешенные подклассы должны находиться в одном Java модуле.