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

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

- что всё это значит и для чего этого вообще нужуно?

Ответ на этот вопрос хорошо ответит картинка ниже.

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

  1. Открыть крышку часов и покрутить шестерёнки (это может привести к поломке).
  2. Использовать специальный винт (безопасно).

Если вдуматься мы пользуемся многими вещами не вникая в то, как именно эти вещи работают.

В данном примере часы. Нам не важно как именно они работают, нам важен факт того, что мы можем получить информацию о текущем времени. Для получения времени мы смотрим на дисплей, для изменения времени мы крутим винт.

Возьмём другой пример "электрочайник", это устройство позволяет изменить температуру воды. Опять же, нам не важно как, нам важно, что вода была холодной, а стала горячей. Для изменения температуры воды мы нажимаем кнопку, хотя могли бы разобрать чайник и замкнуть контакты нагревателя напрямую, но в этом случае есть вероятность получить удар током.

В программировании всё точно так-же. У объектов имеются поля, к некоторым из этих полей нужно закрыть доступ, чтобы напрямую нельзя было менять значение. Как это сделать? Давайте разбираться - это просто!

В файле Person.java

public class Person { String name; String lastname; int age; private int hp; // Добавляем инкапсулированное поле hp (здоровье) public Person(String name, String lastname, int age) { this.name = name; this.lastname = lastname; this.age = age; this.hp = 100; } }

Мы добавили свойство hp перед которым указано ключевое слово private.

Добавив модификатор private мы запретили обращаться к этому полу вне класса.

В файле Main.java

public class Main { public static void main(String[] args) { //Создаём объекты класса Person Person person1 = new Person("Иван", "Иванов", 30); Person person2 = new Person("Вася", "Пупкин", 42); System.out.println(person1.hp); // java: hp has private access in Person } }

Как видно из примера, при запуске программы, мы получаем ошибку java: hp has private access in Person, переводя на русский java: hp имеет приватный доступ у Person.

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

В файле Person.java

public class Person { String name; String lastname; int age; private int hp; // Добавляем инкапсулированное поле hp (здоровье) public Person(String name, String lastname, int age) { this.name = name; this.lastname = lastname; this.age = age; this.hp = 100; } public int getHp() { return hp; } }

В файле Main.java

public class Main { public static void main(String[] args) { //Создаём объекты класса Person Person person1 = new Person("Иван", "Иванов", 30); Person person2 = new Person("Вася", "Пупкин", 42); System.out.println(person1.getHp()); // 100 person1.hp = -20; // java: hp has private access in Person } }

Отлично, получить значение переменной мы сумели, а вот менять её значение не можем, всё по той же причине, она приватная.

И вот самый важный момент, если мы хоим, чтобы изменение переменной происходило в некоторых пределах, то мы можем написать алгоритм по которому будет меняться значение. Смотрим пример:

В файле Person.java

public class Person { String name; String lastname; int age; private int hp; // Добавляем инкапсулированное поле hp (здоровье) public Person(String name, String lastname, int age) { this.name = name; this.lastname = lastname; this.age = age; this.hp = 100; } public int getHp() { return hp; } public void setHp(int hp) { if (this.hp+hp >= 100) this.hp = 100; else if (this.hp + hp <= 0) this.hp = 0; else this.hp = this.hp + hp; } }

В файле Main.java

public class Main { public static void main(String[] args) { //Создаём объекты класса Person Person person1 = new Person("Иван", "Иванов", 30); Person person2 = new Person("Вася", "Пупкин", 42); System.out.println(person1.getHp()); // 100 person1.setHp(500); System.out.println(person1.getHp()); // 100 person1.setHp(-30); System.out.println(person1.getHp()); // 70 person1.setHp(-450); System.out.println(person1.getHp()); // 0 } }

Обратите внимание, теперь мы не можем назначить произвольное значение переменной hp.
Переменная hp теперь может меняться только в пределах от 0 до 100.

Резюме:
Если перед полем или методом указан модификатор private, то получить доступ можно только внутри класса.
Если перед полем или методом указан модификатор public, то получить доступ можно можно из любого класса.
Имеется ещё два модификатора доступа default и protected - о них мы узнаем позже.


Геттеры и сеттеры

Давайте внимательно посмотрим как я назвал методы для обращения к полю hp.
getHp() - get+НазваниеПоля - для получения значения
setHp() - set+НазваниеПоля - для изменения значения

Метод для получения значения называется геттер, начинается обязательно со слова get или is для boolean, затем пишется название поля с большой буквы.

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


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


Комментарии

Добавить комментарий

Чтобы оставить комменатрий необходимо Авторизоваться