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

Кратко — TL;DR
Классы в Java задают шаблон (структуру и поведение) для объектов. Научитесь объявлять класс, добавлять атрибуты, писать конструкторы (по умолчанию, основной, конструктор копирования) и применять модификаторы доступа. Сосредоточьтесь на инкапсуляции (private поля + публичные методы) и выбирайте композицию вместо наследования, когда это целесообразно.
Важно: конструктор может быть не только public — приватный конструктор полезен для паттернов (например, Singleton) и фабрик.
Что такое класс и объект
Кратко: класс — это «чертёж» для создания объектов; объект — экземпляр этого чертежа с конкретным состоянием.
Определение в одну строку: объект — это набор полей (состояние) и методов (поведение), созданный на основе класса.
Класс содержит переменные и методы, которые описывают, какие данные и поведение будут у объектов. Например, класс Student может хранить имя, возраст и курс обучения; каждый конкретный студент — объект этого класса.
Зачем создавать классы в Java
Классы структурируют код, уменьшают дублирование и облегчают поддержку. Вместо того чтобы копировать одно и то же состояние и поведение для похожих сущностей, вы описываете шаблон один раз и создаёте объекты по необходимости.
Бонусы при правильном проектировании:
- легче тестировать;
- проще понимать код;
- повышается повторное использование;
- улучшается безопасность данных через инкапсуляцию.
Объявление класса
Каждый класс объявляют с ключевого слова class; часто перед ним ставят модификатор доступа, например public, чтобы класс был видим в других пакетах.
Правила именования:
- Имя класса обычно начинается с заглавной буквы (CamelCase).
- Имя должно отражать ответственность класса (SRP — single responsibility principle).
Пример минимального объявления класса:
public class Student {
}Фигурные скобки { } ограничивают тело класса: здесь лежат поля, конструкторы и методы.
Поля (атрибуты) класса
Поля (fields) — это переменные, которые описывают состояние объекта. Обычно их делают приватными (private) и предоставляют публичные методы доступа (геттеры/сеттеры).
Пример класса со свойствами:
public class Student {
// поля (переменные экземпляра)
private String fname;
private String lname;
private int age;
private String courseOfStudy;
}Разбор строки объявления поля:
- модификатор доступа: private / public / protected / package-private;
- тип данных: String, int, boolean и т.д.;
- имя переменной: fname, age и т.д.
Примечания:
- String — ссылка на объект строки, начинающаяся с заглавной буквы;
- int — примитивный целочисленный тип, в нижнем регистре;
- Java чувствительна к регистру.
Конструкторы
Конструктор — это специальный метод, который инициализирует новый объект при создании. Он имеет имя класса и не возвращает значение.
Типы конструкторов (основные подходы):
- конструктор по умолчанию (без параметров);
- основной (параметризованный) конструктор;
- конструктор копирования (создаёт новый объект как копию другого).
Пример: класс с конструктором по умолчанию
public class Student {
private String fname;
private String lname;
private int age;
private String courseOfStudy;
// конструктор по умолчанию
public Student() {
this.fname = "John";
this.lname = "Doe";
this.age = 20;
this.courseOfStudy = "Psychology";
}
}Когда вы вызываете new Student(), сработает конструктор по умолчанию и задаст значения полей.
Пример: параметризованный (основной) конструктор
public class Student {
private String fname;
private String lname;
private int age;
private String courseOfStudy;
// конструктор по умолчанию
public Student() {
this.fname = "John";
this.lname = "Doe";
this.age = 0;
this.courseOfStudy = "Psychology";
}
// параметризованный конструктор
public Student(String fname, String lname, int age, String courseOfStudy) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.courseOfStudy = courseOfStudy;
}
}Ключевое слово this указывает на поле текущего объекта и помогает различать параметр и поле с одинаковыми именами.
Пример: конструктор копирования
public class Student {
private String fname;
private String lname;
private int age;
private String courseOfStudy;
// конструктор копирования
public Student(Student other) {
this.fname = other.fname;
this.lname = other.lname;
this.age = other.age;
this.courseOfStudy = other.courseOfStudy;
}
}Конструктор копирования создаёт новый объект с теми же значениями полей, что и переданный объект.
Примечание: если поля содержат изменяемые объекты (например, список), учитывайте необходимость глубокой копии.
Инкапсуляция и модификаторы доступа
Инкапсуляция — ограничение доступа к внутреннему состоянию объекта. Стандартный приём: private поля + public методы доступа (get/set). Это позволяет контролировать валидацию и обеспечивает безопасность состояния.
Пример геттеров и сеттеров:
public String getFname() {
return fname;
}
public void setFname(String fname) {
if (fname == null || fname.isEmpty()) {
throw new IllegalArgumentException("Имя не может быть пустым");
}
this.fname = fname;
}Композиция vs наследование
Ментальная модель: композиция — «имеет» (has-a), наследование — «является» (is-a).
Правило-эвристика: сначала попробуйте композицию; используйте наследование, когда подкласс действительно расширяет или уточняет поведение родителя и не нарушает Liskov Substitution Principle.
Когда классы избыточны (контрпример)
- Небольшие структуры данных, где уместен record (Java 16+);
- Утилитарные функции — статические методы в классе-утилите;
- Простые перечисления — enum;
- Если объект не хранит состояние — можно использовать статические функции или функциональные интерфейсы.
Альтернативы и современные возможности Java
- record (Java 16+) — компактное описание неизменяемых объектов;
- Lombok — генерация геттеров/сеттеров/конструкторов на этапе компиляции (внешняя библиотека);
- Builder pattern — удобен при большом количестве опциональных полей.
Мини-методология проектирования класса (шаги)
- Определите ответственность — одну основную задачу.
- Выберите имя, отражающее эту ответственность.
- Решите, какие данные (поля) нужны и какие должны быть приватными.
- Опишите публичный API — методы, которые будут использоваться внешне.
- Реализуйте конструкторы и подумайте о фабриках или билдере для сложных сценариев.
- Добавьте валидацию в сеттеры/конструкторы.
- Напишите юнит-тесты.
Чек-лист для роли: разработчик / ревьюер / тестировщик
Разработчик:
- класс выполняет одну ответственность;
- поля приватны;
- есть необходимые конструкторы;
- нет утечек мутабельных полей;
- комментарии/документация при необходимости.
Ревьюер:
- читаемость и имена;
- проверка на NullPointer и валидацию;
- проверка циклических зависимостей;
- соблюдение принципов SOLID.
Тестировщик:
- тесты конструктора(ов);
- тесты геттеров/сеттеров с валидацией;
- тесты поведения методов в граничных условиях.
Критерии приёмки
- Класс компилируется без ошибок.
- Имеются юнит-тесты, покрывающие основные сценарии: создание, валидация, поведение методов.
- Нет публичных mutable-полей.
- Документация или JavaDoc для публичного API.
Тест-кейсы / приёмка (примеры)
- Создание Student() по умолчанию — поля заполнены значениями по умолчанию.
- Создание Student(“Иван”, “Иванов”, 21, “Math”) — значения соответствуют переданным параметрам.
- При попытке установить пустое имя — выбрасывается IllegalArgumentException.
- Копирование через конструктор копирования даёт независимый объект (для неизменяемых полей необходимо подтвердить).
Краткий справочник (cheat sheet)
- class MyClass { } — объявление класса;
- private Type field; — приватное поле;
- public MyClass() { } — конструктор по умолчанию;
- public MyClass(Type arg) { this.field = arg; } — параметризованный конструктор;
- public Type getField() / public void setField(Type field) — геттер/сеттер;
- this.field — доступ к полю текущего объекта.
Короткий глоссарий (1 строка на термин)
- Класс: шаблон для создания объектов.
- Объект: экземпляр класса с состоянием и поведением.
- Поле: переменная экземпляра, описывающая состояние.
- Конструктор: метод инициализации объекта.
- Инкапсуляция: сокрытие внутренних данных объекта.
Безопасность и приватные конструкторы
Иногда конструктор делают private для контроля создания экземпляров (фабричные методы, паттерн Singleton). Это нормальная практика, но тогда создание объектов извне ограничено специальным API.
Советы по миграции / совместимости
- При переходе на record: используйте record для неизменяемых DTO;
- Для сложной логики оставляйте обычные классы;
- Если применяете Lombok — убедитесь в совместимости с используемыми инструментами сборки.
Примеры ошибок и как их избежать
- Публичные изменяемые поля — используйте приватные поля и методы доступа.
- Неинициализированные поля — всегда устанавливайте значения в конструкторах или явно при объявлении.
- Неправильное использование наследования — проверьте, действительно ли подкласс является типом родителя.
Итог / Что важно запомнить
- Класс — основа объектно-ориентированного кода в Java.
- Делайте поля private и предоставляйте контролируемый доступ через методы.
- Используйте конструкторы для контроля инвариантов объекта.
- Композиция часто предпочтительнее наследования.
Image Credit: Christina Morillo/ Pexels
Похожие материалы
Как изменить иконки в Windows 10
Советы и безопасность Facebook — полное руководство
Письма из Google Таблиц через Google Scripts
Перезагрузить Linux из командной строки
Flex Time в Logic Pro: точная коррекция тайминга