Класс — это чертёж
До сих пор ваш код жил в методах, которые передавали друг другу простые значения. Класс позволяет объединить связанные данные и работающее с ними поведение в единый именованный тип. Класс — это чертёж; настоящие сущности, с которыми вы работаете, — это объекты, созданные по нему.
Класс объявляет два вида членов: поля (данные, которые хранит каждый объект) и методы (то, что каждый объект умеет делать).
new Dog() создаёт объект в памяти и возвращает вам ссылку на него. d.name и d.bark() обращаются именно к этому объекту.
У каждого объекта своё состояние
Весь смысл класса в том, что вы можете «штамповать» множество независимых объектов, каждый из которых несёт собственные значения полей. Изменение одного никогда не касается другого.
rex и bella — два отдельных объекта. У каждого своё name, поэтому каждый bark() печатает разное значение. Эти данные, привязанные к объекту, называют состоянием экземпляра.
Поля и методы работают вместе
Методы внутри класса могут напрямую читать и обновлять собственные поля объекта — их не нужно передавать как параметры. Метод уже «живёт на» том объекте, чьи данные он трогает.
Обратите внимание, что increment() не принимает аргументов. Он работает с полем, принадлежащим тому Counter, на котором вы его вызвали. В этом и состоит разница между методом класса и свободным статическим методом: у метода есть неявный объект, над которым он действует.
Ключевое слово this
Внутри метода this — это ссылка на объект, на котором был вызван метод. Обычно оно вам не нужно: запись count уже означает this.count. Но this становится незаменимым, когда имя параметра сталкивается с именем поля, что постоянно случается в сеттерах и конструкторах.
Частая ошибка новичков — написать x = x; внутри move. Это лишь присваивает параметр самому себе и оставляет поле нетронутым: компилятор вас не предупредит, а ваш объект молча сохранит свои прежние значения. Именно this.x = x; действительно обновляет поле.
Значения полей по умолчанию и ссылки null
Когда вы создаёте объект, его поля не остаются мусором — Java инициализирует их значениями по умолчанию: 0 для чисел, false для boolean и null для ссылок на объекты вроде String. Это значение null по умолчанию и есть источник классического сбоя.
u.name равно null, потому что его никто не задал, поэтому вызов .length() на нём выбрасывает NullPointerException. Всегда присваивайте объекту осмысленные значения, прежде чем использовать его поля, — именно эту проблему и решают конструкторы.
Организация кода вокруг классов
Реальные программы моделируют свою предметную область как классы, которые держат вместе данные и операции над ними. Здесь единственный класс BankAccount хранит баланс и контролирует, как он меняется:
Данные (balance) и правила их изменения (deposit, withdraw) живут в одном месте. Код из других частей просит счёт что-то сделать, а не ковыряется напрямую в его числах, — это основа чистого и поддерживаемого дизайна.
Далее: конструкторы
Задавать каждое поле вручную после new утомительно и легко забыть — и, как вы только что видели, забытое поле оставляет null, ожидающий сбоя. Конструктор позволяет требовать и инициализировать поля объекта в самый момент его создания, так что BankAccount никогда не сможет существовать без владельца. Об этом — следующая страница.
Часто задаваемые вопросы
Что такое класс в Java?
Класс — это чертёж, который задаёт данные (поля) и поведение (методы) определённого вида объектов. Сам класс — лишь шаблон: реальные объекты вы создаёте из него с помощью new. Например, класс Dog описывает, что у каждой собаки есть name и она умеет bark(), тогда как каждый new Dog() — это отдельная собака со своим именем.
В чём разница между классом и объектом в Java?
Класс — это определение; объект — конкретный экземпляр, построенный по этому определению с помощью new. Один класс Person может породить множество объектов Person, и каждый хранит собственные значения полей. Думайте о классе как о формочке для печенья, а об объектах — как об отдельных печеньях: изменение полей одного объекта никогда не затрагивает другой.
Что делает ключевое слово this в классе Java?
this ссылается на текущий объект — конкретный экземпляр, чей метод сейчас выполняется. Вы используете его для доступа к собственным полям объекта, особенно когда имя параметра совпадает с именем поля (this.name = name;). Без this присваивание просто присвоило бы параметр самому себе, а поле осталось бы без изменений.