Бесплатный открытый урок и вход в объектное программирование: класс и объект, поля, конструктор, методы, this, toString и зачем полям нужен модификатор private. Примеры проверены на JDK 21.
Класс — это новый тип данных
В прошлых уроках данные лежали в отдельных переменных: имя в одной, балл в другой. Как только сущностей становится больше одной, такие переменные начинают путаться. Класс собирает данные и действия над ними в один тип, а объект — это конкретный экземпляр, созданный оператором new.
public class Studenty {
public static void main(String[] args) {
Student anna = new Student("Анна", 92);
Student boris = new Student("Борис", 78);
System.out.println(anna.getImya() + ": " + anna.getBall());
System.out.println(boris);
System.out.println("Борис сдал: " + boris.sdal());
boris.dobavitBally(5);
System.out.println(boris);
}
}
class Student {
private final String imya;
private int ball;
Student(String imya, int ball) {
this.imya = imya;
this.ball = ball;
}
String getImya() {
return imya;
}
int getBall() {
return ball;
}
void dobavitBally(int skolko) {
ball += skolko;
}
boolean sdal() {
return ball >= 60;
}
@Override
public String toString() {
return imya + " (" + ball + ")";
}
}
Анна: 92
Борис (78)
Борис сдал: true
Борис (83)
Оба класса лежат в одном файле Studenty.java: публичным может быть только один класс, и его имя обязано совпадать с именем файла. Так удобно на время учёбы; в рабочем проекте каждый класс кладут в отдельный файл.
Разбор по частям
- Поля
imyaиball— данные объекта. У каждого экземпляра свои значения: изменение балла Бориса не трогает Анну. - Конструктор
Student(String imya, int ball)вызывается приnewи задаёт начальное состояние. Он не возвращает значения и называется так же, как класс. thisразличает поле и параметр с одинаковым именем:this.imya— поле объекта,imya— параметр конструктора. Безthisстрокаimya = imyaприсвоила бы параметр самому себе, и поле осталось бы пустым.- Методы
dobavitBallyиsdal— действия объекта. Метод, объявленный какvoid, ничего не возвращает. toStringвызывается автоматически, когда объект печатают или склеивают со строкой. Без негоprintln(boris)вывел бы что-то вродеStudent@2f92e0f4.finalу поляimyaозначает, что имя задаётся один раз при создании и больше не меняется.
Объекты в списке и статические члены
Объекты складывают в списки так же, как строки и числа. Поле со словом static принадлежит не объекту, а классу целиком: оно одно на все экземпляры, и обращаются к нему через имя класса.
import java.util.ArrayList;
import java.util.List;
public class Polka {
public static void main(String[] args) {
List<Kniga> polka = new ArrayList<>();
polka.add(new Kniga("Мастер и Маргарита", 1967));
polka.add(new Kniga("Понедельник начинается в субботу", 1965));
for (Kniga kniga : polka) {
System.out.println(kniga);
}
System.out.println("Создано книг: " + Kniga.skolkoSozdano());
}
}
class Kniga {
private static int sozdano = 0;
private final String nazvanie;
private final int god;
Kniga(String nazvanie, int god) {
this.nazvanie = nazvanie;
this.god = god;
sozdano++;
}
static int skolkoSozdano() {
return sozdano;
}
@Override
public String toString() {
return nazvanie + ", " + god;
}
}
Мастер и Маргарита, 1967
Понедельник начинается в субботу, 1965
Создано книг: 2
Метод main тоже объявлен как static — именно поэтому он запускается, когда ни одного объекта ещё не существует.
Зачем полям private
Слово private закрывает поле от постороннего кода: снаружи остаются только методы, которые вы разрешили. Это и называется инкапсуляцией. Попытка обойти её не компилируется:
public class Dostup {
public static void main(String[] args) {
Schet schet = new Schet(1000);
schet.ostatok = 1000000;
System.out.println(schet.ostatok);
}
}
class Schet {
private int ostatok;
Schet(int ostatok) {
this.ostatok = ostatok;
}
}
Компилятор ответит ostatok has private access in Schet. Смысл не в секретности, а в контроле: если остаток меняют только методы popolnit и snyat, в них можно проверить сумму и запретить уход в минус. Открытое поле такой проверки не даёт.
Задание для самопроверки
- Напишите класс
Tovarс полями «название», «цена» и «количество», конструктором и методом, возвращающим стоимость позиции. - Соберите список из трёх товаров, напечатайте каждый через
toStringи посчитайте общую стоимость корзины. - Закройте поле «цена» модификатором
privateи добавьте метод изменения цены, который отвергает отрицательные значения.
Что дальше
Это последний урок открытого раздела. Дальше начинается собственно объектное проектирование: наследование и полиморфизм, интерфейсы, исключения, equals и hashCode, разбиение программы на пакеты. Эти темы разбираются на курсе «Основы ООП на Java» с домашними заданиями и проверкой работ преподавателем — программа и условия на странице курсов.
Предыдущий урок — массивы и списки. Все бесплатные занятия собраны в разделе «Уроки Java».