JavaRush/Java блог/Java Developer/Принципы инкапсуляции в Java
Автор
Milan Vucic
Репетитор по программированию в Codementor.io

Принципы инкапсуляции в Java

Статья из группы Java Developer
участников
Привет! Сегодняшнюю лекцию посвятим инкапсуляции и начнем ее сразу с примеров :) Перед тобой — привычный автомат с газировкой. У меня к тебе один вопрос: а как он работает? Попробуй ответить подробно: откуда вываливается стакан, как поддерживается температура внутри, где хранится лед, как автомат понимает, какой сироп добавить и т.д. Вероятнее всего, ответов на эти вопросы у тебя нет. Хорошо, возможно не все пользуются такими автоматами, в нынешнее время они не настолько популярны. Попробуем привести другой пример. Что-нибудь, чем ты точно пользуешься много раз каждый день. О, есть идея! Принципы инкапсуляции - 2 Расскажи, как работает поисковик Google. Как именно он ищет информацию по тем словам, которые ты ввел? Почему наверху находятся эти результаты, а не другие? Хотя ты пользуешься гуглом каждый день, скорее всего, ты этого не знаешь. Но это не важно. Ведь тебе и не нужно этого знать. Ты можешь вводить запросы в поисковик не задумываясь, как именно он работает. Ты можешь купить газировку в автомате, не зная как он устроен. Ты можешь водить машину, не вникая в работу двигателя внутреннего сгорания, и вообще не зная физику даже на школьном уровне. Все это возможно благодаря одному из главных принципов объектно-ориентированного программирования — инкапсуляции. Читая разные статьи на эту тему, наверняка ты сталкивался с тем, что в программировании есть два распространенных понятия — инкапсуляция и сокрытие. И под словом «инкапсуляция» авторы понимают то одно, то другое (так уж сложилось). Мы разберем оба термина, чтобы у тебя было полное понимание. Изначальное значение слова «инкапсуляция» в программировании — объединение данных и методов работы с этими данными в одной упаковке («капсуле»). В Java в роли упаковки-капсулы выступает класс. Класс содержит в себе и данные (поля класса), и методы для работы с этими данными. Принципы инкапсуляции - 3 Тебе это кажется очевидным, но в других концепциях программирования все устроено иначе. Например, в функциональном программировании данные строго отделены от операций над ними. В ООП же (объектно-ориентированном программировании) программы состоят из классов-капсул, которые являются одновременно и данными, и функциями для работы с ними. Теперь поговорим о сокрытии. Как же так получается, что мы пользуемся всякими сложными механизмами без понимания, как они устроены и на чем основана их работа? Все просто: их создатели предоставили простой и удобный интерфейс. На автомате с газировкой интерфейс — это кнопки на панели. Нажав одну кнопку, ты выбираешь объем стакана. Нажав вторую, выбираешь сироп. Третья отвечает за добавление льда. И это все, что тебе нужно сделать. Неважно, как именно автомат устроен внутри. Главное — он устроен так, что для получения газировки пользователю нужно нажать три кнопки. То же и с автомобилем. Неважно, что там происходит у него внутри. Главное — при нажатии правой педали автомобиль едет вперед, а при нажатии левой — тормозит. Именно в этом заключается суть сокрытия. Все «внутренности» программы скрываются от пользователя. Для него эта информация является лишней, ненужной. Пользователю необходим конечный результат, а не внутренний процесс. Давай для примера посмотрим на класс Auto:
public class Auto {

   public void gas() {

       /*внутри автомобиля происходят какие-то сложные вещи
       в результате которых он едет вперед*/
   }

   public void brake() {

       /*внутри автомобиля происходят какие-то сложные вещи
       в результате которых он тормозит*/
   }

   public static void main(String[] args) {

       Auto auto = new Auto();

       //Как все выглядит для пользователя

       //нажал одну педаль - поехал
       auto.gas();

       //нажал другую педаль - затормозил
       auto.brake();
   }
}
Вот как выглядит сокрытие реализации в Java-программе. Все как в реальной жизни: пользователю предоставлен интерфейс (методы). Если ему нужно, чтобы автомобиль в программе выполнил действие, достаточно вызвать нужный метод. А уж что там происходит внутри этих методов — информация лишняя, главное, чтобы все работало как надо. Здесь мы говорили про сокрытие реализации. Кроме него в Java есть еще сокрытие данных. О нем мы писали в лекции про геттеры и сеттеры, но не будет лишним напомнить. Например, у нас есть класс Cat:
public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Мяу!");
   }


}
Возможно, ты запомнил из прошлой лекции, в чем проблема этого класса? Если нет — давай вспомним. Проблема в том, что его данные (поля) открыты для всех, и другой программист легко может создать в программе безымянного кота с весом 0 и возрастом -1000 лет:
public static void main(String[] args) {

   Cat cat = new Cat();
   cat.name = "";
   cat.age = -1000;
   cat.weight = 0;

}
В такой ситуации можно пристально следить за тем, не создает ли кто-то из твоих коллег объектов с неправильным состоянием, но гораздо лучше было бы исключить саму возможность создавать такие «неправильные объекты». Принципы инкапсуляции - 4 С сокрытием данных нам помогают:
  1. модификаторы доступа (private, protected, package default);
  2. геттеры и сеттеры.
Туда можем, например, заложить проверку, не пытается ли кто-то присвоить коту отрицательное число в качестве возраста. Как мы говорили ранее, авторы разных статей об инкапсуляции имеют в виду либо инкапсуляцию (объединение данных и методов), либо сокрытие, либо и то, и другое. В Java присутствуют оба механизма (в других ООП-языках это не обязательно так), так что последний вариант будет наиболее правильным. Использование инкапсуляции дает нам несколько важных преимуществ:
  1. Контроль за корректным состоянием объекта. Примеры этому были выше: благодаря сеттеру и модификатору private, мы обезопасили нашу программу от котов с весом 0.

  2. Удобство для пользователя за счет интерфейса. Мы оставляем «снаружи» для доступа пользователя только методы. Ему достаточно вызвать их, чтобы получить результат, и совсем не нужно вникать в детали их работы.

  3. Изменения в коде не отражаются на пользователях. Все изменения мы проводим внутри методов. На пользователя это не повлияет: он как писал auto.gas() для газа машины, так и будет писать. А то, что мы поменяли что-то в работе метода gas() для него останется незаметным: он, как и раньше, просто будет получать нужный результат.
Комментарии (99)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Михаил Вотяков
Уровень 23
11 апреля, 08:38
"То же и с автомобилем. Неважно, что там происходит у него внутри. Главное — при нажатии правой педали автомобиль едет вперед, а при нажатии левой — тормозит." - На самом деле, очень важно понимать, что происходит внутри, иначе мы встречаем ситуации когда "ОЙ... Я перепутала педали", или "я не могу работать, мне нужен новый компухтер, потому что на экране написано нажмите ОК чтобы продолжить" *Последнее это чисто сисадминская боль"
Maxim Iatiuc
Уровень 1
26 апреля, 10:42
Вы привели примеры, когда человек не умеет пользоваться техникой. Это немного другое. Для того, чтобы не путать педали, не обязательно вникать в работу двигателя внутреннего сгорания. С компьютером тоже самое, достаточно знать куда кликать и как пользоваться им, но не обязательно для этого знать как всё устроенно внутри и тд.
Kuttubek7 Java Developer в Google
15 марта, 18:17
Заебись обьяснил
Vladislav Gorokhov
Уровень 32
11 февраля, 05:57
Хорошая статья, запомнить бы теорию
LeoAtrox
Уровень 25
7 декабря 2023, 15:43
Стоп, получается сам вызов метода это тоже уже инкапсуляция? Это же слишком обыденно...
Daniil
Уровень 24
Expert
23 января, 11:12
Да, постоянно с ней сталкиваешься, но лучше знать "Врага" в лицо
chess.rekrut
Уровень 25
18 августа 2023, 13:09
easy
Alexander Rozenberg
Уровень 32
25 июля 2023, 13:25
fine
No Name
Уровень 32
25 июня 2023, 07:41
+ статья в копилке
Ислам
Уровень 33
5 июня 2023, 17:27
Nice
Aquarus
Уровень 20
12 января 2023, 13:05
""" То же и с автомобилем. Неважно, что там происходит у него внутри. Главное — при нажатии правой педали автомобиль едет вперед, а при нажатии левойтормозит. """ Автор видать на картинге часто гоняет.... (:
Vadim Shapovalov
Уровень 22
16 февраля 2023, 07:45
Это называется "автоматическая коробка передач".
Виктор
Уровень 40
17 февраля 2023, 11:29
АКПП эт))). Вы видимо ездили только на механике?)))
Юрий Даниленко
Уровень 10
3 апреля 2023, 10:20
Ну тут речь все таки, наверное, про то, что автомобиль при нажатии на газ не только вперед ехать может. А вот на картинге как раз, таки нет задней передачи
partiec
Уровень 33
27 декабря 2022, 09:24
В книгах советских времен можно вычитать типа: - Мы с другом ходили на завод пить газировку из автомата. или - Мой дед - литейщик, мог выпить за раз литр ситро! статья в этом стиле 😀👍