В статье рассказывается:
- Что такое инкапсуляция в ООП
- Преимущества инкапсуляции
- Отличие инкапсуляции от сокрытия
- Инкапсуляция в Java
- Инкапсуляция в Python
- Возможности инкапсуляции в C++
-
Пройди тест и узнай, какая сфера тебе подходит:
айти, дизайн или маркетинг.Бесплатно от Geekbrains
Что такое инкапсуляция? В объектно-ориентированном программировании под этим понятием принято подразумевать заключение данных и функционала в оболочку. При этом речь не идет о сокрытии, это лишь часть инкапсуляции.
В качестве такой оболочки могут выступать классы, которые концентрируют данные в одном месте и закрывают их от воздействий извне (собственно, скрывают). Начинающие программисты порой задаются вопросом, зачем же вообще используется инкапсуляция, не до конца понимая ее ценности. Давайте же с этим разберемся.
Что такое инкапсуляция в ООП
Для начала постараемся объяснить, что такое инкапсуляция простыми словами. Мысленно перенесемся примерно лет на 140 в прошлое. Тогда автомобили еще были в диковинку, а первые образцы таких транспортных средств с паровыми моторами вызывали много критических комментариев.
Их называли шумными монстрами, загрязняющими воздух и пугающими лошадей. Человеку, который управлял таким авто, нужно было четко понимать, как все работает, внимательно наблюдать за температурой, наличием нужного объема воды и регулярно подбрасывать уголь для дальнейшего движения. Вместо простого рулевого управления в тех средствах передвижения было два рычага, каждый из которых обеспечивал поворот одного колеса. Понятно, что управлять первым автомобилем было совсем не просто.
Эволюция автопрома изменила не только внешний автомобиля, но и его оснащение. Мы уже привыкли к усилителям тормозов, автоматическим КПП и другим узлам, которые сделали управление машиной комфортным и простым. За своевременную доставку бензина в камеры сгорания теперь отвечает топливный насос, поршневая система, газораспределительный механизм и другие элементы силового агрегата обеспечивают движение автомобиля.
Работа всех деталей скрыта от водителя, который просто нажимает на акселератор и может не иметь никакого представления о том, что в этом момент происходит с инжектором или дросселем. Это действительно можно назвать ощутимым прогрессом. Благодаря тому, что все процессы, которые происходят внутри узлов авто, скрыты, управление транспортным средством является достаточно простой задачей.
Это понятие имеет тесную связь с интерфейсом класса. Практически все элементы, которые не входят в интерфейс, подлежат инкапсуляции в классе.
Преимущества инкапсуляции
Что такое инкапсуляция, и почему она так важна? Возьмём в качестве примера код масштабного проекта, который весит в совокупности гигабайт. В нем все может быть сильно взаимосвязано между собой. А теперь вопрос: получится ли проанализировать такой код? Представим, что такая возможность есть, но, судя по всему, от преобразования каждого из имеющихся методов будет зависеть уровень стабильности, который в данном случае будет снижен.
входят в ТОП-30 с доходом
от 210 000 ₽/мес
Скачивайте и используйте уже сегодня:
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ бесплатных нейросетей для упрощения работы и увеличения заработка
Только проверенные нейросети с доступом из России и свободным использованием
ТОП-100 площадок для поиска работы от GeekBrains
Список проверенных ресурсов реальных вакансий с доходом от 210 000 ₽
Объектно-ориентированное программирование направлено на то, чтобы проецировать реальность на код. Так, в обычном мире вода, которой наполнен стакан, не может проникать в его стенки. Клавиша клавиатуры не будет причастна к вычислениям, а мозг человека не станет помогать сердцу по перекачиванию крови. Можно точно так же рассмотреть и вопрос, что такое инкапсуляция в сетях. Ее принцип заключается в скрытии связей, то есть дает возможность «не перемешиваться».
Числом открытых связей между объектом Х и другими элементами измеряется легкость кода. Учитывая многочисленные внутренние переплетения, можно говорить о сложности восприятия. Наделить объект Х объективным наименование будет даже не так просто, ведь он включает достаточно много различных данных о себе.
Не только в командах private и protected проявляется инкапсуляция. Безо всяких опасений создавайте четырёхъярусные алгоритмы внутри метода класса, ведь он инкапсулирует в себе алгоритм и переменные.
При чтении нечеткого алгоритма программист, нуждающийся в классе, обратит внимание на содержимое метода, а не на его наименование. Это также инкапсуляция, в действие приведен принцип сокрытия. Для программиста не имеет значения внутреннее содержание, однако он представляет, как все взаимодействует.
Это же касается и функций замыкания, которые предназначены для обособления алгоритма с переменными. Другими словами, функционирование также направлено на инкапсуляцию, ведь переменные внутри функции, а алгоритм, который их использует, не беспокоит того, кто ее использует. Стоит заметить, что на сегодняшний день в программировании инкапсулируется больше функций, чем ключевой слово в классах. Такие примеры часто встречаются в JavaScript.
Отличие инкапсуляции от сокрытия
Теперь поговорим о том, что такое инкапсуляция данных и чем она отличается от сокрытия.
Нам часто приходится использовать непростые механизмы, не осознавая принцип их устройства и то, на чем базируется их действие. Это происходит потому, что разработчики сформировали легкий и практичный интерфейс. Рассмотрим еще примеры, которые помогут разобраться, что такое инкапсуляция.
Автомат с кофе включает в себя простой интерфейс – это клавиши, которые расположены на панели для выбора напитка, его объема и количество сахара. В этом и заключается весь принцип работы устройства, который нам необходимо знать для его использования.
В этом и состоит смысл сокрытия. Его используют, чтобы скрыть внутреннее устройство программы от пользователя. Ведь ему важен только конечный результат, а эти сведения для него не нужны и не имею никакого значения.
Инкапсуляция в Java
В Java мы используем различные методы, благодаря которым обеспечивается принцип инкапсуляции. Каким путем это осуществляется?
Существуют методы регулирования доступа к имеющимся сведениям, среди которых:
- Ключевые слова доступа (Access modifiers).
- Геттеры и Сеттеры (Getters and Setters).
Модификаторы доступа – это конкретные слова, определяющие тех, кому доступны или не доступны для использования данные.
Существует несколько основных модификаторов доступа:
- Public – «публичный, доступный всем».
- Default – «по умолчанию». Это значение по умолчанию, в ситуации отсутствия модификатора доступа. Сведения с данным словом доступны в пределах package (упаковка).
- Protected – «защищенный». Имеет сходство с default, но отличается тем, что доступ есть и у классов наследников.
- Private – «частный, личный». Эти сведения видны лишь самому классу.
на обучение «Программист Java» до 24 ноября
Как обеспечивается принцип безопасности? Существует возможность без труда менять данную переменную и строку, что не совсем хорошо, так как каждый может это сделать из любой части программы.
Если нам этого не нужно, мы меняем модификатор с public на private:
class MyClass {
private String s = «Hello World!»;
}
1
2
3
class MyClass {
private String s = «Hello World!»;
}
В этом случае при попытке доступа к переменной s (чтение или запись) возникнет ошибка. Таким способом нам удалось обезопасить переменную от недоброжелателей.
Самое важное, что нам удается контролировать происходящее. Теперь никто не имеет возможности изменять или читать наши переменные.
Инкапсуляция в Python
В системе «Пайтон» предусмотрен трехуровневый доступ к данным:
- публичный (public, отсутствует специальный синтаксис, publicBanana);
- защищенный (protected, выделяется одиночным нижним подчеркиванием в начальной части названия, protectedBanana);
- приватный (private, выделяется двойным нижним подчеркиванием в начальной части названия, privateBanana).
Избежать инкапсуляции можно с помощью языка, который дает специалисту программирования синтаксический инструмент. Это и есть тот самый выход, при котором доступно чтение и возможность изменения частных переменных, а также можно вызывать частные функции.
«Магические методы» (magic methods), которые также именуются как «специальные» (special methods) предоставляют классам возможность устанавливать собственное поведение относительно базовых языков операторов. Среди данных языков операторов можно выделить выражение вида:
- x > y
- x[ i ]
Python поддерживает множество таких методов. Полный список можно найти на странице официальной документации языка. Инициализатор __init__ является наиболее часто используемым и запускается при создании нового объекта класса.
Другой, __lt__ (расширенное сравнение), определяет правила для сравнения двух объектов пользовательского класса. Такие методы не попадают в категорию «приватных» или «публичных», поскольку служат другим целям и корнями глубоко уходят во внутреннюю структуру языка.
#!/usr/bin/python3
class Phone:
def __init__(self, number): # magic method / inititalizer
print( «The Phone object was created» )
self.number = number
def __lt__(self, other): # magic method / rich comparison
return self.number < other.number
my_phone = Phone(20)
other_phone = Phone(30)
if my_phone < other_phone:
print( «Two instances of custom class were compared» )
print( «‘__lt__’ was called implicitly» )
if my_phone.__lt__(other_phone):
print( «Now, ‘__lt__’ was used explicitly» )
input( «Press Enter to exit» )
Магические методы имеет возможность вызывать каждый пользователь тем же путем, что и любой публичный метод в Python. Они рассчитаны для неявного применения в конкретных ситуациях. Особый случай для __init__ заключается в инициализации нового объекта класса. В то время как метод __lt__ предназначен для сравнительного анализа пары объектов.
Возможности инкапсуляции в C++
Изначально принято, что в классе (class) данные и методы приватные, а доступ к их чтению и изменению присутствует только у класса, к которому они относятся. Степень доступа можно преобразовать путем соответствующих ключевых слов, предоставляемых Си++.
Си++ предоставляет некоторое количество спецификаторов, которые преобразовывают доступ к данным следующим путем:
- публичные (public) данные;
- защищенные (protected), которым присутствует доступ только для класса и дочерних классов;
- приватные (private) —доступ есть лишь для класса, к которому принадлежат.
Приведем пример инкапсуляции: В классе Contact, публичные переменные и методы доступны из основной программы (main). Приватные переменные и методы может читать, вызывать и изменять лишь сам класс.
#include <iostream>
using namespace std;
class Contact
{
private:
int mobile_number; // private variable
int home_number; // private variable
public:
Contact() // constructor
{
mobile_number = 12345678;
home_number = 87654321;
}
void print_numbers()
{
cout << «Mobile number: » << mobile_number;
cout << «, home number: » << home_number << endl;
}
};
int main()
{
Contact Tony;
Tony.print_numbers();
// cout << Tony.mobile_number << endl;
// will cause compile time error
return 0;
}
Сбой при компиляции может произойти в случае попытки напечатать или преобразовать приватную переменную mobile_number из главной программы (main), так как в классе ограниченный доступ к приватным данным.
Си++ включает в себя ключевое слово «друг» (friend), предоставляющее возможность установить дополнительные исключения в основные условия доступа к данным. В случае, когда функция или класс именуются «другом» класса Contact , им предоставляется свободный доступ к защищенным или приватным элементам.
Установлены два условия дружбы: она не наследуется и не взаимна. Плюс ко всему, степень защищенности данных не зависит от имеющихся «друзей», в связи с чем приватные данные являются такими с исключением в форме «друга».
#include <iostream>
using namespace std;
class Contact
{
private:
int mobile_number; // private variable
int home_number; // private variable
public:
Contact() // constructor
{
mobile_number = 12345678;
home_number = 87654321;
}
// Declaring a global ‘friend’ function
friend void print_numbers( Contact some_contact );
};
void print_numbers( Contact some_contact )
{
cout << «Mobile number: » << some_contact.mobile_number;
cout << «, home number: » << some_contact.home_number << endl;
}
int main()
{
Contact Tony;
print_numbers(Tony);
return 0;
}
Здесь print_numbers() является стандартной функцией, а не методом класса Contact. Ее доступ к приватным переменным обеспечивается объявлением, по которому функция print_numbers() выступает «другом» класса Contact. Код не будет компилироваться при отсутствии строки, определяющей «друга».
Язык Си++ унаследовал много инструментов из своего предшественника Си. В их числе находится и преобразование типов (typecasting). Безусловно, приватными считаются все переменные и методы класса. При этом открыт стандартный доступ к элементам структуры (struct). Он является публичным.
В этом случае появляется возможность для формирования структуры и публичного класса, который будет содержать набор данных расположенных также, как и в классе Contact. Затем методом преобразования типов можно обеспечить доступ к данным private.
Читайте также!
Примеры применения инкапсуляции можно найти не только в объективно-ориентированных языках. Современные системы ООП обеспечивают максимальное удобство и естественность такого метода. Есть немало вариантов, позволяющих нарушить инкапсуляцию, но уход от недобросовестных методов позволит и в дальнейшем использовать ее в языках Си или Си++.