undefined

Инкапсуляция

Java Core
1 уровень , 7 лекция
Открыта

— Привет, Амиго! Хочу посвятить сегодняшнюю лекцию инкапсуляции. Ты уже знаешь в общих чертах, что это такое.

Инкапсуляция - 1

В чем же преимущества инкапсуляции? Их достаточно много, но я могу выделить четыре, на мой взгляд, основных:

1) Валидное внутреннее состояние.

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

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

Если мы не хотим, чтобы какая-то переменная класса менялась другими классами, мы объявляем ее private, и тогда только методы её же класса смогут получить к ней доступ. Если мы хотим, чтобы значения переменных можно было только читать, но не изменять, тогда нужно добавить public getter для нужных переменных.

Например, мы хотим, чтобы все могли узнать количество элементов в нашей коллекции, но никто не мог его поменять без нашего разрешения. Тогда мы объявляем переменную private int count и метод public getCount().

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

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

2) Контроль передаваемых аргументов.

Иногда нужно контролировать аргументы, передаваемые в методы нашего класса. Например, наш класс описывает объект «человек» и позволяет задать дату его рождения. Мы должны проверять все передаваемые данные на их соответствие логике программы и логике нашего класса. Например, не допускать 13-й месяц, дату рождения 30 февраля и так далее.

— А зачем кому-то указывать в дате рождения 30 февраля?

— Во-первых – это может быть ошибка ввода данных от пользователя.

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

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

Вот только, когда наступит 30 марта программа не найдет никого, т.к. в календаре нет 32 марта. В программе становится гораздо меньше ошибок, когда в методы добавляют проверку переданных данных.

— Помню, когда мы изучали ArrayList, я смотрел его код, и там была проверка индекса в методах get и set: index больше или равен нулю и меньше длины массива. Там еще кидалось исключение, если в массиве нет элемента с таким индексом.

— Да, это классический пример проверки входных данных.

3) Минимизация ошибок при изменении кода классов.

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

Класс оказался настолько полезен, что ты решил его улучшить. Но если ты удалишь какие-то методы этого класса, то код десятков людей перестанет компилироваться. Им придется срочно все переделывать. И чем больше переделок, тем больше ошибок. Ты поломаешь кучу сборок, и тебя будут ненавидеть.

А когда мы меняем методы, объявленные как private, мы знаем, что нигде нет ни одного класса, который вызывал бы эти методы. Мы можем их переделать, поменять количество параметров и их типы, и зависимый код будет работать дальше. Ну, или как минимум, компилироваться.

4) Задаем способ взаимодействия нашего объекта со сторонними объектами.

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

Инкапсуляция - 2

Инкапсуляция позволяет добавлять дополнительные ограничения, которые можно превратить в дополнительные преимущества. Например, класс String реализован как immutable (неизменяемый) объект. Объект класса String неизменяем с момента создания и до момента смерти. Все методы класса String (remove, substring, …), возвращают новую строку, абсолютно не изменяя объект, у которого они были вызваны.

— Ничего себе. Вот оно как, оказывается.

— Инкапсуляция очень интересная штука.

— Ага.

Комментарии (133)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Nick 20 уровень
15 апреля 2021
Судя по по картинке инкапсуляция - это кишки. И не царское это дело лазить в эти кишки - царское это опять же из картинки - кормить!
Just me 17 уровень, Гомель
18 марта 2021
Если кратко: Инкапсуляция - это механизм ограничения доступа к необходимым компонентам объекта путем объединения данных и методов работы с этими данными в защищенной от изменения "капсуле" (упаковке). В Java в роли упаковки-капсулы выступает класс. Пример:

public class Main {
    public static void main(String[] args) {
        Cat Fili = new Cat();
        Fili.age = 12;  //Ошибка т.к. age - private
        Fili.setAge(100); //Не ппройдет проверку
    }
}

public class Cat {
    private int age = 1;

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        if (age > 0 && age < 30)
            this.age = age;
        else System.out.println("Wrong age");
    }
}

Имя Фамилия 16 уровень, Москва
11 января 2021
Ты поломаешь множество чужих судеб кучу сборок, и тебя будут ненавидеть.
Regina Bulanova 19 уровень, Рязань
20 декабря 2020
Инкапсуляция = сокрытие, изолирование части кода. А чем более изолированны части кода друг от друга (например, классы), тем сложнее что-либо сломать. В принципе это все, что нужно понять из лекции:)
🦔 Виктор 20 уровень, Москва Expert
8 декабря 2020
Выжимка лекции: Правильное использование инкапсуляции гарантирует, что ни один класс не может получить прямой доступ к внутренним данным нашего класса и, следовательно, изменить их без контроля с нашей стороны. Только через вызов методов того же класса, что и изменяемые переменные. Класс String реализован как immutable (неизменяемый) объект. Объект класса String неизменяем с момента создания и до момента смерти. Все методы класса String (remove, substring, …), возвращают новую строку, абсолютно не изменяя объект, у которого они были вызваны. Ещё мне очень понравилась ёмкая формулировка инкапсуляции из этой статьи: «Инкапсуляция в Java означает ограничение доступа к данным и возможностям их изменения».
Arman Tursynbek 17 уровень, Алматы
22 ноября 2020
ТЫ СМОЖЕШЬ!! Иногда устаешь, и вообще ничего не хочется делать. Порой нужно просто сделать первый шаг для того, чтобы войти в процесс. Не ожидай от себя ничего и не оценивай то, что получилось. ПРОСТО ДЕЛАЙ! Вдохновение и силы придут в процессе, но их легко убить стремлением к идеальности всегда и во всем. Ты - проводник, не критикуй себя по мелочам. Хвали себя за то, что ты уже сделал. Даже если это самый маленький шаг, даже если ты просто вывел "Hello world!" , он все равно приблизил тебя к мечте!
dmitrii_94 15 уровень, Кишинёв
28 октября 2020
Ребят держите ссылку на книгу "Полное руководство Java. "file:///Users/mcbook/Downloads/Java%208.%20%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D0%B5%20%D1%80%D1%83%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4%D1%81%D1%82%D0%B2%D0%BE.%20(%20PDFDrive%20).pdf 1. Заходим по ссылке 2. Нажимаем на (cmd + F) 3. Набираем в поисковую строку название темы или технологии 4. Читаем вдумчиво
Alec I 16 уровень
8 октября 2020
слишком много воды в данной статье и мало примеров с кодом (котом) для понимания :)
aleksdenni 22 уровень, Полтава
30 сентября 2020
Копия моего кота)))
Vladimir “Rain_Senpai1995” Soldatenko 35 уровень, Киев
14 сентября 2020
Единственное, что я понял, если ты знаешь инкапсуляцию "...тебя будут ненавидеть"🙃