Java с нуля: от переменных до ООП

Этот курс предназначен для начинающих, желающих освоить фундаментальные основы языка Java. Вы пройдете путь от изучения синтаксиса и типов данных до глубокого понимания принципов объектно-ориентированного программирования.

1. Введение в Java: установка окружения, структура программы, переменные и примитивные типы данных

Введение в Java: установка окружения, структура программы, переменные и примитивные типы данных

Добро пожаловать на курс Java с нуля: от переменных до ООП. Это первая статья, с которой начнется ваше путешествие в мир одного из самых популярных и востребованных языков программирования в мире. Java используется везде: от мобильных приложений на Android до серверных систем крупнейших банков и корпораций.

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

Почему Java?

Главная особенность Java — это принцип WORA (Write Once, Run Anywhere — «Пиши один раз, запускай везде»). Это означает, что программа, написанная на Windows, без изменений запустится на Linux или macOS.

!Схема работы принципа кроссплатформенности Java через виртуальную машину.

Это достигается благодаря JVM (Java Virtual Machine) — виртуальной машине, которая переводит универсальный код Java в понятные команды для конкретного процессора.

Установка окружения

Чтобы начать программировать, нам понадобятся два компонента:

  • JDK (Java Development Kit) — набор инструментов разработчика. Он включает в себя компилятор и библиотеки.
  • IDE (Integrated Development Environment) — среда разработки. Это «умный блокнот», который помогает писать код, ищет ошибки и подсказывает синтаксис.
  • Шаг 1: Установка JDK

    Для начала обучения рекомендуется использовать одну из последних стабильных версий (LTS), например, JDK 17 или JDK 21.

  • Перейдите на сайт Oracle или Adoptium (OpenJDK).
  • Скачайте установщик для вашей операционной системы.
  • Установите JDK, следуя инструкциям инсталлятора.
  • Шаг 2: Установка IntelliJ IDEA

    Мы будем использовать IntelliJ IDEA Community Edition. Это бесплатная и самая мощная среда для Java.

  • Скачайте Community версию с официального сайта JetBrains.
  • Установите программу.
  • Первая программа: Hello World

    Запустите IntelliJ IDEA и создайте новый проект (New Project). Назовите его JavaCourse. В папке src создайте новый Java-класс с именем Main.

    Напишите следующий код (или скопируйте его, но лучше напишите руками для запоминания):

    Запустите программу, нажав на зеленый треугольник рядом со строкой main. В консоли внизу вы увидите вывод: Привет, мир!.

    Разбор структуры программы

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

  • public class Main — Объявление класса. В Java всё является классом. Представьте, что класс — это чертеж или инструкция. Имя файла должно совпадать с именем класса (Main.java содержит class Main).
  • { ... } — Фигурные скобки ограничивают тело класса или метода. Всё, что внутри, относится к этому блоку.
  • public static void main(String[] args) — Это точка входа в программу. Когда вы запускаете приложение, Java ищет именно этот метод main, чтобы начать выполнение.
  • * public — метод доступен всем. * static — метод можно вызвать без создания объекта (об этом поговорим в будущем). * void — метод ничего не возвращает (не выдает результат-число, а просто делает действие).
  • System.out.println("..."); — Команда вывода текста на экран (в консоль). ln в конце означает «line», то есть после вывода курсор перейдет на новую строку.
  • Переменные: коробки для данных

    Программы работают с данными. Чтобы сохранить данные в памяти, мы используем переменные.

    > Переменная — это именованная область памяти, в которую можно положить значение определенного типа.

    Представьте переменную как коробку. У коробки есть:

  • Тип (форма коробки: для круглых предметов, для квадратных).
  • Имя (подпись на коробке: «Игрушки», «Документы»).
  • Значение (то, что лежит внутри).
  • !Визуальная метафора переменных как коробок с данными.

    Объявление и инициализация

    Синтаксис создания переменной в Java:

    Пример:

    Здесь мы создали переменную типа int (целое число) с именем age и положили в нее значение 25.

    Правила именования переменных: * Имя должно начинаться с буквы. * Используйте стиль camelCase (первое слово с маленькой, каждое следующее — с большой): myFirstVariable, userAge. * Имя должно быть осмысленным.

    Примитивные типы данных

    Java — язык со строгой типизацией. Это значит, что вы не можете положить слона в коробку из-под спичек. Если переменная объявлена как целое число, вы не можете записать в нее текст.

    В Java существует 8 примитивных типов данных. Они являются строительными блоками для всего остального.

    1. Целые числа (Integer types)

    Используются для счета предметов, индексов, идентификаторов.

    | Тип | Размер (бит) | Примерное описание | | :--- | :--- | :--- | | byte | 8 | Очень маленькие числа | | short | 16 | Маленькие числа | | int | 32 | Стандартный выбор для целых чисел | | long | 64 | Огромные числа (банковские счета, время) |

    Диапазон значений зависит от количества бит. Формула для вычисления диапазона знаковых чисел:

    Где — это количество бит, выделенных под тип данных. Например, для типа byte, где , диапазон будет от до .

    Примеры в коде:

    2. Числа с плавающей точкой (Floating-point types)

    Используются для дробных чисел.

    | Тип | Размер (бит) | Точность | | :--- | :--- | :--- | | float | 32 | Одинарная точность (6-7 знаков) | | double | 64 | Стандартный выбор (15-16 знаков) |

    Примеры:

    3. Символьный тип (Character type)

    Хранит один символ в кодировке Unicode.

    * char (16 бит)

    Значение пишется в одинарных кавычках:

    4. Логический тип (Boolean type)

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

    * boolean

    А как же текст?

    Вы наверняка заметили, что мы не упомянули текст. В Java текст хранится в типе String. Важно знать: String не является примитивным типом. Это ссылочный тип (класс), но используется он настолько часто, что ведет себя похоже на примитивы.

    Текст пишется в двойных кавычках:

    Операции с переменными

    С переменными можно производить математические действия.

    Особое внимание стоит уделить операции остаток от деления (%). Она возвращает то, что осталось после целочисленного деления.

    Заключение

    Сегодня вы сделали огромный шаг — настроили окружение и написали свою первую программу. Вы узнали, что данные в Java имеют строгие типы, и научились создавать переменные.

    В следующей статье мы научим нашу программу «думать»: разберем условные операторы и циклы, чтобы код мог принимать решения в зависимости от данных.

    2. Управление потоком выполнения: условные операторы if-else, switch и работа с циклами

    Управление потоком выполнения: условные операторы if-else, switch и работа с циклами

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

    Сегодня мы научим нашу программу «думать». Мы разберем, как выполнять код только при определенных условиях и как заставить компьютер делать рутинную работу за нас, повторяя действия сотни и тысячи раз.

    Логические ветвления: оператор if

    В жизни мы постоянно используем конструкцию «ЕСЛИ — ТО». Если на улице дождь, то я беру зонт. Если магазин открыт, то я покупаю хлеб.

    В Java для этого используется оператор if. Его структура выглядит так:

    !Схема работы условного оператора if.

    Операторы сравнения

    Чтобы сформулировать условие, нам нужны инструменты сравнения. Результатом любой такой операции всегда является boolean (true или false).

    | Оператор | Описание | Пример (при a=5, b=3) | | :--- | :--- | :--- | | == | Равно | a == b (false) | | != | Не равно | a != b (true) | | > | Больше | a > b (true) | | < | Меньше | a < b (false) | | >= | Больше или равно | a >= 5 (true) | | <= | Меньше или равно | b <= 3 (true) |

    Важно: Не путайте оператор присваивания = (положить значение в коробку) и оператор сравнения == (сравнить две коробки).

    Блок else и else if

    Часто нам нужно не просто пропустить действие, а выполнить альтернативное. Если дождь — берем зонт, иначе — надеваем солнечные очки.

    Компьютер проверяет условия сверху вниз. Как только он находит первое истинное условие (true), он выполняет соответствующий блок кода и пропускает все остальные.

    Оператор выбора: switch

    Иногда у нас есть одна переменная, которая может принимать множество конкретных значений. Например, дни недели или оценки в школе. Использовать кучу if-else в таком случае неудобно и некрасиво.

    Здесь на помощь приходит switch (переключатель).

    Разбор конструкции switch

  • case: Метка, с которой сравнивается переменная. Если значение совпало, выполняется код после двоеточия.
  • break: Критически важная команда. Она прерывает выполнение switch. Если забыть break, программа продолжит выполнять все следующие case подряд, игнорируя проверки, пока не встретит break или конец блока. Это называется «проваливанием» (fall-through).
  • default: Выполняется, если ни один из case не подошел (аналог последнего else).
  • Циклы: сила повторения

    Представьте, что вам нужно вывести фразу «Я люблю Java» 5 раз. Вы можете написать System.out.println 5 раз. А если нужно 1000 раз? Или 1 000 000?

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

    Цикл while (Пока)

    Самый простой цикл. Он работает по принципу: «Пока условие истинно — делай».

    Если условие изначально ложно (например, apples = 0), код внутри цикла не выполнится ни разу.

    Цикл do-while

    Этот цикл похож на while, но с одним отличием: проверка условия происходит после выполнения тела цикла. Это гарантирует, что код выполнится хотя бы один раз.

    В примере выше условие number < 5 ложно сразу (10 не меньше 5), но фраза «Число: 10» все равно выведется один раз.

    Цикл for (Для)

    Это самый популярный и универсальный цикл в Java. Он идеально подходит, когда мы точно знаем, сколько раз нужно повторить действие (например, пройтись по всем элементам списка).

    Синтаксис может показаться сложным, но он очень логичен:

    Разберем на примере счетчика от 1 до 5:

    !Жизненный цикл итерации в цикле for.

    Как это работает пошагово:

  • Инициализация (int i = 1): Создается переменная-счетчик. Выполняется только один раз в самом начале.
  • Условие (i <= 5): Перед каждой итерацией проверяется это условие. Если true — идем внутрь цикла. Если false — цикл завершается.
  • Тело цикла: Выполняется код внутри {}.
  • Обновление (i++): После выполнения тела цикла счетчик изменяется.
  • Переход к шагу 2.
  • Математический пример

    Допустим, нам нужно посчитать сумму чисел от 1 до . В математике это записывается как:

    Где — итоговая сумма, — конечное число, а — переменная счетчика, которая увеличивается на 1 с каждым шагом.

    В коде это выглядит так:

    Управление внутри циклов: break и continue

    Иногда нам нужно вмешаться в работу цикла прямо в процессе выполнения.

    * break: Мгновенно останавливает цикл и выходит из него (так же, как в switch). * continue: Пропускает оставшуюся часть кода в текущей итерации и переходит к следующей.

    Пример с continue: выведем только четные числа.

    Бесконечный цикл

    Будьте осторожны! Если условие цикла всегда будет истинным, программа «зависнет» и будет работать вечно (пока вы не закроете её принудительно).

    Заключение

    Теперь ваша программа умеет принимать решения и выполнять сложные повторяющиеся задачи. Вы освоили: * Условный оператор if-else для ветвления логики. * Оператор switch для выбора из множества вариантов. * Циклы while, do-while и for для повторения действий.

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

    3. Работа с данными: массивы, строки и основы управления памятью

    Работа с данными: массивы, строки и основы управления памятью

    В предыдущих статьях мы научились хранить одиночные данные в переменных и управлять ходом программы с помощью циклов и условий. Но что, если нам нужно сохранить не одно число, а тысячу? Например, оценки всех учеников школы или температуру воздуха за каждый день года. Создавать тысячу переменных temp1, temp2 ... temp1000 — это путь в никуда.

    Сегодня мы познакомимся с массивами, углубимся в работу со строками и приоткроем завесу тайны над тем, как Java управляет памятью, разделяя её на Stack и Heap.

    Массивы: упорядоченные коллекции

    > Массив (Array) — это структура данных, хранящая набор значений одного типа под одним именем.

    Представьте массив как ряд пронумерованных почтовых ящиков в подъезде. Весь ряд имеет одно имя (например, «Ящики дома №5»), но чтобы получить почту, нужно знать номер конкретного ящика.

    !Визуализация массива из 5 элементов с индексами от 0 до 4.

    Создание и инициализация

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

    Обратите внимание на квадратные скобки []. Они указывают на то, что перед нами массив.

    Доступ к элементам

    Самое важное правило, которое нужно запомнить навсегда:

    Нумерация элементов в Java начинается с НУЛЯ.

    Если длина массива равна , то индексы находятся в диапазоне от до .

    Пусть — это массив. Тогда доступ к элементу осуществляется так:

    Где — имя массива, — индекс элемента, а — присваиваемое значение.

    Ошибка ArrayIndexOutOfBoundsException

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

    Перебор массива

    Массивы и циклы созданы друг для друга. Чтобы обработать все данные, мы используем цикл for.

    Свойство .length возвращает длину массива.

    Существует также упрощенная версия цикла, называемая for-each. Она используется, когда нам не важен индекс, а нужны только сами значения:

    Многомерные массивы

    Массивы могут быть не только линейными, но и двумерными (таблицы), трехмерными и так далее. Двумерный массив — это «массив массивов».

    Строки: больше, чем просто текст

    Мы уже использовали тип String. Но в отличие от int или boolean, строка — это объект, а не примитив. Это сложный тип данных, у которого есть свои методы (функции).

    Пул строк (String Pool)

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

    Неизменяемость (Immutability)

    Строки в Java нельзя изменить.

    Когда вы пишете:

    На самом деле старая строка "Hello" не меняется. Создается совершенно новая строка "Hello World", и переменная s начинает ссылаться на неё. Старая строка остается в памяти, пока её не удалит сборщик мусора.

    Сравнение строк

    Это одна из самых частых ошибок новичков.

    * Оператор == сравнивает ссылки (адреса в памяти). * Метод .equals() сравнивает содержимое (текст).

    Всегда используйте .equals() для сравнения текста!

    Полезные методы строк

    | Метод | Описание | Пример | | :--- | :--- | :--- | | length() | Длина строки | "Hi".length() -> 2 | | charAt(int index) | Символ по индексу | "Java".charAt(0) -> 'J' | | substring(int start, int end) | Часть строки | "Hello".substring(0, 2) -> "He" | | toUpperCase() | Перевод в верхний регистр | "hi".toUpperCase() -> "HI" |

    Основы управления памятью: Stack и Heap

    Чтобы понять, как работают массивы и объекты, нужно заглянуть «под капот» Java. Память делится на две основные области: Стек (Stack) и Куча (Heap).

    !Схематичное изображение памяти Java: ссылки хранятся в стеке, а сами объекты — в куче.

    Stack (Стек)

    Это быстрая оперативная память для выполнения текущих методов.

    * Здесь хранятся примитивные переменные (int, double, boolean). * Здесь хранятся ссылки на объекты. * Когда метод завершается, его блок в стеке очищается мгновенно.

    Heap (Куча)

    Это большое хранилище для всех объектов.

    * Здесь хранятся сами объекты (String, массивы, ваши будущие классы). * Доступ сюда медленнее, чем к стеку. * Очисткой занимается специальный процесс — Garbage Collector (Сборщик мусора).

    Ссылочные типы данных

    Когда вы создаете массив или строку:

    Происходит следующее:

  • В Heap (куче) выделяется место под 3 числа: {1, 2, 3}.
  • В Stack (стеке) создается переменная arr.
  • В переменную arr записывается не сам массив, а адрес (ссылка), где этот массив лежит в куче.
  • Именно поэтому массивы и строки называют ссылочными типами.

    Null — ссылка в никуда

    Если переменная ссылочного типа никуда не указывает, её значение равно null.

    Попытка вызвать метод у null приводит к самой известной ошибке в Java — NullPointerException. Это как попытка позвонить по номеру, которого не существует.

    Заключение

    Сегодня мы сделали важный шаг от простых переменных к сложным структурам данных. Мы узнали: * Как хранить наборы данных в массивах. * Почему нумерация начинается с нуля. * Как правильно сравнивать строки через .equals(). * В чем разница между примитивами (живут в стеке) и объектами (живут в куче).

    Эти знания понадобятся нам в следующей статье, где мы начнем создавать свои собственные типы данных и погрузимся в мир Объектно-Ориентированного Программирования (ООП).

    4. Методы и модульность: объявление функций, параметры, перегрузка и область видимости переменных

    Методы и модульность: объявление функций, параметры, перегрузка и область видимости переменных

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

    Представьте, что вы пишете программу для интернет-магазина. Вам нужно рассчитать скидку для клиента в десяти разных местах программы. Копировать один и тот же код 10 раз — плохая идея. Если правила скидок изменятся, вам придется искать и исправлять код во всех десяти местах.

    Решение этой проблемы — методы (в других языках их часто называют функциями). Это именованные блоки кода, которые можно вызывать столько раз, сколько нужно.

    Что такое метод?

    > Метод — это законченная последовательность действий (подпрограмма), направленная на решение отдельной задачи, у которой есть имя.

    Мы уже использовали методы, даже не задумываясь об этом. System.out.println() — это метод, который умеет выводить текст на экран. Нам не нужно знать, как именно он управляет пикселями монитора, нам достаточно знать его имя и то, что он делает.

    !Визуальная метафора метода: данные входят, обрабатываются и результат выходит наружу.

    Анатомия метода

    Давайте посмотрим, из чего состоит объявление метода в Java. Напишем метод, который просто складывает два числа.

    Разберем каждое слово:

  • Модификаторы (public static): О них мы поговорим подробнее в теме ООП. Пока просто запомните: чтобы вызывать метод из main, он должен быть static.
  • Тип возвращаемого значения (int): Это тип данных, который метод «выдаст» в результате своей работы. Если метод ничего не возвращает, пишется слово void.
  • Имя метода (sum): Название действия. Принято называть методы глаголами в стиле camelCase (calculatePrice, sendMessage).
  • Параметры (int a, int b): Переменные, которые метод принимает на вход. Их может быть сколько угодно, или не быть вовсе.
  • Тело метода ({ ... }): Блок кода, который выполняется при вызове.
  • Оператор return: Завершает работу метода и возвращает результат.
  • Параметры и аргументы

    Часто новички путают понятия «параметр» и «аргумент». Разница проста:

    Параметры — это переменные, указанные при создании* (объявлении) метода. Это «места» для будущих данных. Аргументы — это конкретные значения, которые мы передаем в метод при его вызове*.

    Пример вызова нашего метода sum:

    Когда метод запускается, значения аргументов копируются в параметры. Внутри метода sum переменная a станет равна 10, а b — 20.

    Возвращаемые значения и void

    Метод может работать как рабочий на заводе: вы даете ему детали, он собирает их и отдает готовое изделие. Это «изделие» и есть возвращаемое значение.

    Для возврата используется ключевое слово return. После него метод немедленно прекращает работу.

    Математический пример

    Допустим, нам нужно написать метод для вычисления площади круга. Формула выглядит так:

    Где — площадь круга, — математическая константа (примерно 3.14), а — радиус круга.

    В коде это будет выглядеть так:

    Методы void

    Иногда нам не нужно получать ответ от метода. Например, метод должен просто вывести текст в консоль, сохранить файл или отправить письмо. В таком случае в качестве типа возвращаемого значения указывается void (пустота).

    Перегрузка методов (Method Overloading)

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

    Представьте, что вы хотите написать метод sum, который умеет складывать не только целые числа (int), но и дробные (double).

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

    * sum(5, 10) -> вызовет первый метод. * sum(5.5, 10.2) -> вызовет второй метод. * sum(1, 2, 3) -> вызовет третий метод.

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

    Область видимости переменных (Scope)

    Одна из самых важных концепций для понимания работы методов — это область видимости.

    > Переменная доступна (видна) только внутри того блока кода { ... }, в котором она была объявлена.

    Локальные переменные

    Переменные, объявленные внутри метода, называются локальными. Они рождаются, когда выполнение доходит до строчки их объявления, и умирают, когда метод завершается. Другие методы ничего не знают о локальных переменных друг друга.

    Блочная видимость

    Это правило работает и для вложенных блоков, например, внутри циклов или условий if.

    Принцип DRY и модульность

    Использование методов помогает следовать главному принципу программирования: DRY (Don't Repeat Yourself — Не повторяйся).

    Если вы видите, что копируете один и тот же кусок кода второй или третий раз — остановитесь. Выделите этот код в отдельный метод.

    Преимущества модульности:

  • Читаемость: Код calculateSalary() понятнее, чем 20 строк формул.
  • Легкость изменений: Ошибку нужно исправить только в одном месте.
  • Переиспользование: Метод можно вызывать из разных частей программы.
  • Заключение

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

    Мы разобрали: * Как объявлять методы и возвращать значения. * Разницу между параметрами и аргументами. * Как работает перегрузка методов. * Почему переменные не видны за пределами своих блоков.

    Эти знания станут фундаментом для следующей большой темы — Объектно-Ориентированного Программирования (ООП), где методы станут частью чего-то большего — классов и объектов.

    5. Основы ООП: создание классов и объектов, инкапсуляция, наследование и полиморфизм

    Основы ООП: создание классов и объектов, инкапсуляция, наследование и полиморфизм

    До этого момента мы писали программы в процедурном стиле: данные лежали отдельно (в переменных), а действия — отдельно (в методах). Пока программа маленькая, это работает отлично. Но представьте, что вы создаете сложную игру-стратегию. У вас есть сотни юнитов: лучники, рыцари, драконы. У каждого свои характеристики (здоровье, урон) и свое поведение.

    Если использовать только массивы и методы, ваш код превратится в хаос из тысяч переменных. Здесь на сцену выходит Объектно-Ориентированное Программирование (ООП). Это подход, который позволяет моделировать реальный мир в коде, объединяя данные и поведение в единые сущности — объекты.

    В этой статье мы разберем четыре кита, на которых держится Java: Классы/Объекты, Инкапсуляция, Наследование и Полиморфизм.

    Классы и объекты: чертеж и результат

    Самая частая аналогия для понимания ООП — это чертеж и дом.

    * Класс (Class) — это чертеж, схема или шаблон. Он описывает, какими свойствами и умениями будет обладать объект. Сам по себе класс памяти почти не занимает и ничего не делает. * Объект (Object) — это конкретный экземпляр, созданный по этому чертежу. Это реальная сущность в памяти компьютера.

    !Класс — это инструкция по сборке, а объекты — это конкретные роботы, созданные по этой инструкции.

    Создание класса

    Давайте создадим класс Cat (Кот). У кота есть состояние (имя, возраст) и поведение (мяукать).

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

    Теперь, имея чертеж, мы можем создать конкретных котов в методе main.

    Обратите внимание на ключевое слово new. Именно оно дает команду Java выделить память в Heap (куче) для нового объекта.

    Инкапсуляция: защита данных

    В примере выше мы напрямую обращались к полям: cat1.age = 3. Это выглядит просто, но это опасно. Что если кто-то напишет cat1.age = -100? Котов с отрицательным возрастом не бывает, но программа это проглотит, а потом сломается в неожиданном месте.

    Инкапсуляция — это механизм, который объединяет данные и методы, работающие с этими данными, и защищает их от внешнего вмешательства.

    Суть инкапсуляции можно выразить правилом: «Скрывай внутреннее устройство, предоставляй доступ только через методы».

    Модификаторы доступа

    Для управления доступом в Java используются специальные слова:

  • public — доступно всем.
  • private — доступно только внутри этого же класса.
  • Давайте защитим нашего кота:

    Теперь никто не сможет сломать данные объекта, присвоив некорректное значение. Мы управляем доступом через «пульт управления» — методы get и set.

    Наследование: не повторяйся

    Представьте, что нам нужно создать классы для разных животных: Cat, Dog, Cow. У всех них есть общие черты: имя, возраст, умение есть и спать. Писать один и тот же код в трех разных файлах — нарушение принципа DRY (Don't Repeat Yourself).

    Наследование позволяет создать общий класс (родитель) и на его основе создавать более специфичные классы (потомки).

    !Схема наследования показывает, как дочерние классы перенимают свойства родителя.

    В Java для наследования используется ключевое слово extends.

    Теперь объект класса Dog умеет делать всё, что умеет Animal, плюс то, что мы добавили в Dog.

    Полиморфизм: один интерфейс, много форм

    Это самая сложная для понимания, но самая мощная концепция ООП. Слово «полиморфизм» греческого происхождения и означает «много форм».

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

    Переопределение методов (Overriding)

    Допустим, у нас есть метод makeSound() (издать звук) в классе Animal. Но животные издают разные звуки. Собака лает, кот мяукает.

    Мы можем переопределить поведение родительского метода в дочернем классе.

    Магия полиморфизма

    Теперь самое интересное. Поскольку и Cat, и Dog являются Animal, мы можем хранить их в переменной типа Animal.

    Зачем это нужно? Представьте, что у вас есть массив всех животных в зоопарке. Вы можете пройтись по нему циклом и каждому сказать makeSound(), не задумываясь, кто именно там сидит — лев, жираф или пингвин. Каждый отреагирует по-своему.

    Это делает программу гибкой. Если вы добавите нового зверя (например, Cow), вам не придется переписывать код, который управляет зоопарком. Вы просто создадите новый класс, и он автоматически встроится в систему.

    Конструкторы: рождение объекта

    Когда мы пишем new Cat(), мы вызываем особый метод — конструктор. Его задача — подготовить объект к работе (например, сразу заполнить имя).

    Конструктор называется так же, как класс, и не имеет типа возвращаемого значения.

    Ключевое слово this используется, чтобы указать на текущий объект. this.name означает «поле name этого объекта», а просто name — это параметр, пришедший в конструктор.

    Заключение

    Сегодня мы перевернули ваше представление о программировании. Мы перешли от написания инструкций к моделированию мира.

  • Класс — это шаблон, Объект — реализация.
  • Инкапсуляция защищает данные с помощью private и геттеров/сеттеров.
  • Наследование (extends) позволяет переиспользовать код.
  • Полиморфизм позволяет работать с разными объектами одинаково.
  • В следующей статье мы углубимся в нюансы Java: узнаем про абстрактные классы, интерфейсы и ключевое слово static, которое мы использовали, но еще не разбирали подробно.